This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/5] Atomic type qualifier - front end changes


Teach the front ends to handle __attribute__((atomic)) and set the ATOMIC_TYPE bit in the type tree.

Also add RID_ATOMIC and recognize the _Atomic keyword, and treat it like __attribute__((atomic)) was specified.

Places that set TREE_THIS_VOLATILE and TREE_SIDE_EFFECTS for volatile symbols also need to set these fields for atomic variables. All through the middle end we have always treated atomics as volatile in order to avoid any kind of optimization.


	c-family
	* c-common.h (enum rid): Add RID_ATOMIC.
	* c-common.c (struct c_common_resword c_common_r): Add "_Atomic".
	(struct attribute_spec c_common_att): Add "atomic" attribute.
	(handle_atomic_attribute): New.  Add atomic qualifier to type.
	(sync_resolve_params): Use MAIN_VARIANT as cast for the non-atomic
	parameters.
	(keyword_is_type_qualifier): Add RID_ATOMIC;
	* c-format.c (check_format_types): Add atomic as a qualifer check.
	* c-pretty-print.c (pp_c_cv_qualifiers): Handle atomic qualifier.

	c
	* c-tree.h (struct c_declspecs): Add atomic_p field.
	* c-aux-info.c (gen_type): Handle atomic qualifier.
	* c-decl.c (shadow_tag_warned): Add atomic_p to declspecs check.
	(quals_from_declspecs): Add atomic_p to declspecs check.
	(grokdeclarator): Check atomic and warn of duplicate or errors.
	(build_null_declspecs): Handle atomic_p.
	(declspecs_add_qual): Handle RID_ATOMIC.
	* c-parser.c (c_token_starts_typename): Add RID_ATOMIC.
	(c_token_is_qualifier, c_token_starts_declspecs): Add RID_ATOMIC.
	(c_parser_declspecs, c_parser_attribute_any_word): Add RID_ATOMIC.
	* c-typeck.c (build_indirect_ref): Treat atomic as volatile.
	(build_array_ref, convert_for_assignment): Treat atomic as volatile.

	objc
	* objc-act.c (objc_push_parm): Treat atomic as volatile.

	cp
	* cp-tree.h (CP_TYPE_ATOMIC_P): New macro.
	(enum cp_decl_spec): Add ds_atomic.
	* class.c (build_simple_base_path): Treat atomic as volatile.
	* cvt.c (diagnose_ref_binding): Handle atomic.
	(convert_from_reference, convert_to_void): Treat atomic as volatile.
	* decl.c (grokfndecl): Treat atomic as volatile.
	(build_ptrmemfunc_type): Set TYPE_ATOMIC.
	(grokdeclarator): handle atomic qualifier.
	* mangle.c (dump_substitution_candidates): Add atomic to the qualifier
	list.
	* parser.c (cp_parser_type_specifier): Handle RID_ATOMIC.
	(cp_parser_cv_qualifier_seq_opt): Handle RID_ATOMIC.
	(set_and_check_decl_spec_loc): Add atomic to decl_spec_names[].
	* pt.c (check_cv_quals_for_unify): Add TYPE_QUAL_ATOMIC to check.
	* rtti.c (qualifier_flags): Set atomic qualifier flag.
	* semantics.c (non_const_var_error): Check CP_TYPE_ATOMIC_P too.
	* tree.c (cp_build_qualified_type_real): Add TYPE_QUAL_ATOMIC.
	(cv_unqualified): Add TYPE_QUAL_ATOMIC to mask.
	* typeck.c (build_class_member_access_expr): Treat atomic as volatile.
	(cp_build_indirect_ref, cp_build_array_ref): Treat atomic as volatile.
	(check_return_expr, cp_type_quals): Treat atomic as volatile.
	(cv_qualified_p): Add TYPE_QUAL_ATOMIC to mask.


Index: gcc/c-family/c-common.h
===================================================================
*** gcc/c-family/c-common.h	(revision 201248)
--- gcc/c-family/c-common.h	(working copy)
*************** enum rid
*** 66,72 ****
    RID_UNSIGNED, RID_LONG,    RID_CONST, RID_EXTERN,
    RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE,
    RID_VOLATILE, RID_SIGNED,  RID_AUTO,  RID_RESTRICT,
!   RID_NORETURN,
  
    /* C extensions */
    RID_COMPLEX, RID_THREAD, RID_SAT,
--- 66,72 ----
    RID_UNSIGNED, RID_LONG,    RID_CONST, RID_EXTERN,
    RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE,
    RID_VOLATILE, RID_SIGNED,  RID_AUTO,  RID_RESTRICT,
!   RID_NORETURN, RID_ATOMIC,
  
    /* C extensions */
    RID_COMPLEX, RID_THREAD, RID_SAT,
Index: gcc/c-family/c-common.c
===================================================================
*** gcc/c-family/c-common.c	(revision 201248)
--- gcc/c-family/c-common.c	(working copy)
*************** static tree handle_unused_attribute (tre
*** 325,330 ****
--- 325,331 ----
  static tree handle_externally_visible_attribute (tree *, tree, tree, int,
  						 bool *);
  static tree handle_const_attribute (tree *, tree, tree, int, bool *);
+ static tree handle_atomic_attribute (tree *, tree, tree, int, bool *);
  static tree handle_transparent_union_attribute (tree *, tree, tree,
  						int, bool *);
  static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
*************** const struct c_common_resword c_common_r
*** 401,406 ****
--- 402,408 ----
  {
    { "_Alignas",		RID_ALIGNAS,   D_CONLY },
    { "_Alignof",		RID_ALIGNOF,   D_CONLY },
+   { "_Atomic",		RID_ATOMIC,    D_CONLY },
    { "_Bool",		RID_BOOL,      D_CONLY },
    { "_Complex",		RID_COMPLEX,	0 },
    { "_Imaginary",	RID_IMAGINARY, D_CONLY },
*************** const struct attribute_spec c_common_att
*** 637,642 ****
--- 639,646 ----
    /* The same comments as for noreturn attributes apply to const ones.  */
    { "const",                  0, 0, true,  false, false,
  			      handle_const_attribute, false },
+   { "atomic",		      0, 0, false, true, false,
+ 			      handle_atomic_attribute, false},
    { "transparent_union",      0, 0, false, false, false,
  			      handle_transparent_union_attribute, false },
    { "constructor",            0, 1, true,  false, false,
*************** handle_const_attribute (tree *node, tree
*** 6842,6847 ****
--- 6846,6879 ----
    return NULL_TREE;
  }
  
+ 
+ /* Handle an "atomic" attribute; arguments as in
+    struct attribute_spec.handler.  */
+ 
+ static tree
+ handle_atomic_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+ 			int ARG_UNUSED (flags), bool *no_add_attrs)
+ {
+   bool ignored = true;
+   if (TYPE_P (*node) && TREE_CODE (*node) != ARRAY_TYPE)
+     {
+       tree type = *node;
+ 
+       if (!TYPE_ATOMIC (type))
+ 	{
+ 	  *node = build_qualified_type (type, TYPE_QUAL_ATOMIC);
+ 	  ignored = false;
+ 	}
+     }
+ 
+   if (ignored)
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       *no_add_attrs = true;
+     }
+   return NULL_TREE;
+ }
+ 
  /* Handle a "transparent_union" attribute; arguments as in
     struct attribute_spec.handler.  */
  
*************** sync_resolve_params (location_t loc, tre
*** 10012,10022 ****
    unsigned int parmnum;
  
    function_args_iter_init (&iter, TREE_TYPE (function));
!   /* We've declared the implementation functions to use "volatile void *"
       as the pointer parameter, so we shouldn't get any complaints from the
       call to check_function_arguments what ever type the user used.  */
    function_args_iter_next (&iter);
    ptype = TREE_TYPE (TREE_TYPE ((*params)[0]));
  
    /* For the rest of the values, we need to cast these to FTYPE, so that we
       don't get warnings for passing pointer types, etc.  */
--- 10044,10055 ----
    unsigned int parmnum;
  
    function_args_iter_init (&iter, TREE_TYPE (function));
!   /* We've declared the implementation functions to use "atomic volatile void *"
       as the pointer parameter, so we shouldn't get any complaints from the
       call to check_function_arguments what ever type the user used.  */
    function_args_iter_next (&iter);
    ptype = TREE_TYPE (TREE_TYPE ((*params)[0]));
+   ptype = TYPE_MAIN_VARIANT (ptype);
  
    /* For the rest of the values, we need to cast these to FTYPE, so that we
       don't get warnings for passing pointer types, etc.  */
*************** keyword_is_type_qualifier (enum rid keyw
*** 11388,11393 ****
--- 11421,11427 ----
      case RID_CONST:
      case RID_VOLATILE:
      case RID_RESTRICT:
+     case RID_ATOMIC:
        return true;
      default:
        return false;
Index: gcc/c-family/c-format.c
===================================================================
*** gcc/c-family/c-format.c	(revision 201248)
--- gcc/c-family/c-format.c	(working copy)
*************** check_format_types (format_wanted_type *
*** 2374,2379 ****
--- 2374,2380 ----
  		  && pedantic
  		  && (TYPE_READONLY (cur_type)
  		      || TYPE_VOLATILE (cur_type)
+ 		      || TYPE_ATOMIC (cur_type)
  		      || TYPE_RESTRICT (cur_type)))
  		warning (OPT_Wformat_, "extra type qualifiers in format "
  			 "argument (argument %d)",
Index: gcc/c-family/c-pretty-print.c
===================================================================
*** gcc/c-family/c-pretty-print.c	(revision 201248)
--- gcc/c-family/c-pretty-print.c	(working copy)
*************** pp_c_cv_qualifiers (c_pretty_printer *pp
*** 186,193 ****
--- 186,201 ----
    if (p != NULL && (*p == '*' || *p == '&'))
      pp_c_whitespace (pp);
  
+   if (qualifiers & TYPE_QUAL_ATOMIC)
+     {
+       pp_c_ws_string (pp, func_type ? "__attribute__((atomic))" : "atomic");
+       previous = true;
+     }
+ 
    if (qualifiers & TYPE_QUAL_CONST)
      {
+       if (previous)
+         pp_c_whitespace (pp);
        pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
        previous = true;
      }
Index: gcc/c/c-tree.h
===================================================================
*** gcc/c/c-tree.h	(revision 201248)
--- gcc/c/c-tree.h	(working copy)
*************** struct c_declspecs {
*** 328,333 ****
--- 328,335 ----
    BOOL_BITFIELD volatile_p : 1;
    /* Whether "restrict" was specified.  */
    BOOL_BITFIELD restrict_p : 1;
+   /* Whether "_Atomic" was specified.  */
+   BOOL_BITFIELD atomic_p : 1;
    /* Whether "_Sat" was specified.  */
    BOOL_BITFIELD saturating_p : 1;
    /* Whether any alignment specifier (even with zero alignment) was
Index: gcc/c/c-aux-info.c
===================================================================
*** gcc/c/c-aux-info.c	(revision 201248)
--- gcc/c/c-aux-info.c	(working copy)
*************** gen_type (const char *ret_val, tree t, f
*** 285,290 ****
--- 285,292 ----
        switch (TREE_CODE (t))
  	{
  	case POINTER_TYPE:
+ 	  if (TYPE_ATOMIC (t))
+ 	    ret_val = concat ("atomic ", ret_val, NULL);
  	  if (TYPE_READONLY (t))
  	    ret_val = concat ("const ", ret_val, NULL);
  	  if (TYPE_VOLATILE (t))
*************** gen_type (const char *ret_val, tree t, f
*** 425,430 ****
--- 427,434 ----
  	  gcc_unreachable ();
  	}
      }
+   if (TYPE_ATOMIC (t))
+     ret_val = concat ("atomic ", ret_val, NULL);
    if (TYPE_READONLY (t))
      ret_val = concat ("const ", ret_val, NULL);
    if (TYPE_VOLATILE (t))
Index: gcc/c/c-decl.c
===================================================================
*** gcc/c/c-decl.c	(revision 201248)
--- gcc/c/c-decl.c	(working copy)
*************** shadow_tag_warned (const struct c_declsp
*** 3712,3717 ****
--- 3712,3718 ----
                     && declspecs->typespec_kind != ctsk_tagfirstref
  		   && (declspecs->const_p
  		       || declspecs->volatile_p
+ 		       || declspecs->atomic_p
  		       || declspecs->restrict_p
  		       || declspecs->address_space))
  	    {
*************** shadow_tag_warned (const struct c_declsp
*** 3801,3806 ****
--- 3802,3808 ----
  
    if (!warned && !in_system_header && (declspecs->const_p
  				       || declspecs->volatile_p
+ 				       || declspecs->atomic_p
  				       || declspecs->restrict_p
  				       || declspecs->address_space))
      {
*************** quals_from_declspecs (const struct c_dec
*** 3832,3837 ****
--- 3834,3840 ----
    int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0)
  	       | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
  	       | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)
+ 	       | (specs->atomic_p ? TYPE_QUAL_ATOMIC : 0)
  	       | (ENCODE_QUAL_ADDR_SPACE (specs->address_space)));
    gcc_assert (!specs->type
  	      && !specs->decl_attr
*************** grokdeclarator (const struct c_declarato
*** 4911,4916 ****
--- 4914,4920 ----
    int constp;
    int restrictp;
    int volatilep;
+   int atomicp;
    int type_quals = TYPE_UNQUALIFIED;
    tree name = NULL_TREE;
    bool funcdef_flag = false;
*************** grokdeclarator (const struct c_declarato
*** 5065,5070 ****
--- 5069,5075 ----
    constp = declspecs->const_p + TYPE_READONLY (element_type);
    restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
    volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
+   atomicp = declspecs->atomic_p + TYPE_ATOMIC (element_type);
    as1 = declspecs->address_space;
    as2 = TYPE_ADDR_SPACE (element_type);
    address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1;
*************** grokdeclarator (const struct c_declarato
*** 5077,5082 ****
--- 5082,5090 ----
  	pedwarn (loc, OPT_Wpedantic, "duplicate %<restrict%>");
        if (volatilep > 1)
  	pedwarn (loc, OPT_Wpedantic, "duplicate %<volatile%>");
+       if (atomicp > 1)
+ 	pedwarn (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");
+ 
      }
  
    if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2)
*************** grokdeclarator (const struct c_declarato
*** 5090,5095 ****
--- 5098,5104 ----
    type_quals = ((constp ? TYPE_QUAL_CONST : 0)
  		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
  		| (volatilep ? TYPE_QUAL_VOLATILE : 0)
+ 		| (atomicp ? TYPE_QUAL_ATOMIC : 0)
  		| ENCODE_QUAL_ADDR_SPACE (address_space));
  
    /* Warn about storage classes that are invalid for certain
*************** grokdeclarator (const struct c_declarato
*** 5651,5656 ****
--- 5660,5670 ----
  	      FOR_EACH_VEC_SAFE_ELT_REVERSE (arg_info->tags, ix, tag)
  		TYPE_CONTEXT (tag->type) = type;
  	    }
+ 	    if (atomicp)
+ 	      {
+ 		error_at (loc, "_Atomic type qualifier in function declarator");
+ 		type = error_mark_node;
+ 	      }
  	    break;
  	  }
  	case cdk_pointer:
*************** build_null_declspecs (void)
*** 8825,8830 ****
--- 8839,8845 ----
    ret->thread_p = false;
    ret->const_p = false;
    ret->volatile_p = false;
+   ret->atomic_p = false;
    ret->restrict_p = false;
    ret->saturating_p = false;
    ret->alignas_p = false;
*************** declspecs_add_qual (source_location loc,
*** 8886,8891 ****
--- 8901,8910 ----
        specs->restrict_p = true;
        specs->locations[cdw_restrict] = loc;
        break;
+     case RID_ATOMIC:
+       dupe = specs->atomic_p;
+       specs->atomic_p = true;
+       break;
      default:
        gcc_unreachable ();
      }
Index: gcc/c/c-parser.c
===================================================================
*** gcc/c/c-parser.c	(revision 201248)
--- gcc/c/c-parser.c	(working copy)
*************** c_token_starts_typename (c_token *token)
*** 489,494 ****
--- 489,495 ----
  	case RID_UNION:
  	case RID_TYPEOF:
  	case RID_CONST:
+ 	case RID_ATOMIC:
  	case RID_VOLATILE:
  	case RID_RESTRICT:
  	case RID_ATTRIBUTE:
*************** c_token_is_qualifier (c_token *token)
*** 571,576 ****
--- 572,578 ----
  	case RID_VOLATILE:
  	case RID_RESTRICT:
  	case RID_ATTRIBUTE:
+ 	case RID_ATOMIC:
  	  return true;
  	default:
  	  return false;
*************** c_token_starts_declspecs (c_token *token
*** 651,656 ****
--- 653,659 ----
  	case RID_ACCUM:
  	case RID_SAT:
  	case RID_ALIGNAS:
+ 	case RID_ATOMIC:
  	  return true;
  	default:
  	  return false;
*************** c_parser_static_assert_declaration_no_se
*** 1948,1955 ****
--- 1951,1960 ----
       restrict
       volatile
       address-space-qualifier
+      atomic
  
     (restrict is new in C99.)
+    (atomic is new in C11.)
  
     GNU extensions:
  
*************** c_parser_declspecs (c_parser *parser, st
*** 2171,2176 ****
--- 2176,2185 ----
  	  t = c_parser_typeof_specifier (parser);
  	  declspecs_add_type (loc, specs, t);
  	  break;
+ 	case RID_ATOMIC:
+ 	  if (!flag_isoc11)
+ 	    pedwarn (loc, 0, "_Atomic qualifier provided in ISO C11");
+ 	  /* Fallthru.  */
  	case RID_CONST:
  	case RID_VOLATILE:
  	case RID_RESTRICT:
*************** c_parser_attribute_any_word (c_parser *p
*** 3487,3492 ****
--- 3496,3502 ----
  	case RID_SAT:
  	case RID_TRANSACTION_ATOMIC:
  	case RID_TRANSACTION_CANCEL:
+ 	case RID_ATOMIC:
  	  ok = true;
  	  break;
  	default:
Index: gcc/c/c-typeck.c
===================================================================
*** gcc/c/c-typeck.c	(revision 201248)
--- gcc/c/c-typeck.c	(working copy)
*************** build_indirect_ref (location_t loc, tree
*** 2268,2276 ****
  	  /* A de-reference of a pointer to const is not a const.  It is valid
  	     to change it via some other pointer.  */
  	  TREE_READONLY (ref) = TYPE_READONLY (t);
! 	  TREE_SIDE_EFFECTS (ref)
! 	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
! 	  TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
  	  protected_set_expr_location (ref, loc);
  	  return ref;
  	}
--- 2268,2276 ----
  	  /* A de-reference of a pointer to const is not a const.  It is valid
  	     to change it via some other pointer.  */
  	  TREE_READONLY (ref) = TYPE_READONLY (t);
! 	  TREE_SIDE_EFFECTS (ref) = (TYPE_VOLATILE (t) || TYPE_ATOMIC (t)
! 				     || TREE_SIDE_EFFECTS (pointer));
! 	  TREE_THIS_VOLATILE (ref) = (TYPE_VOLATILE (t) || TYPE_ATOMIC (t));
  	  protected_set_expr_location (ref, loc);
  	  return ref;
  	}
*************** build_array_ref (location_t loc, tree ar
*** 2408,2416 ****
--- 2408,2418 ----
  	    | TREE_READONLY (array));
        TREE_SIDE_EFFECTS (rval)
  	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
+ 	    | TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (array)))
  	    | TREE_SIDE_EFFECTS (array));
        TREE_THIS_VOLATILE (rval)
  	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
+ 	    | TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (array)))
  	    /* This was added by rms on 16 Nov 91.
  	       It fixes  vol struct foo *a;  a->elts[1]
  	       in an inline function.
*************** convert_for_assignment (location_t locat
*** 5578,5585 ****
  	  else if (TREE_CODE (ttr) != FUNCTION_TYPE
  		   && TREE_CODE (ttl) != FUNCTION_TYPE)
  	    {
! 	      if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
! 		  & ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
  		{
  		  WARN_FOR_QUALIFIERS (location, 0,
  				       G_("passing argument %d of %qE discards "
--- 5580,5589 ----
  	  else if (TREE_CODE (ttr) != FUNCTION_TYPE
  		   && TREE_CODE (ttl) != FUNCTION_TYPE)
  	    {
! 	      /* Assignments between atomic and non-atomic objects are OK since
! 	         the atomic access is always through an interface call.  */
! 	      if (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr)
! 		  & ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttl))
  		{
  		  WARN_FOR_QUALIFIERS (location, 0,
  				       G_("passing argument %d of %qE discards "
Index: gcc/objc/objc-act.c
===================================================================
*** gcc/objc/objc-act.c	(revision 201248)
--- gcc/objc/objc-act.c	(working copy)
*************** objc_push_parm (tree parm)
*** 8244,8249 ****
--- 8244,8250 ----
    c_apply_type_quals_to_decl
    ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
     | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
+    | (TYPE_ATOMIC (TREE_TYPE (parm)) ? TYPE_QUAL_ATOMIC : 0)
     | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
  
    objc_parmlist = chainon (objc_parmlist, parm);
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h	(revision 201248)
--- gcc/cp/cp-tree.h	(working copy)
*************** enum languages { lang_c, lang_cplusplus,
*** 1293,1298 ****
--- 1293,1302 ----
  #define CP_TYPE_VOLATILE_P(NODE)			\
    ((cp_type_quals (NODE) & TYPE_QUAL_VOLATILE) != 0)
  
+ /* Nonzero if this type is atomic-qualified.  */
+ #define CP_TYPE_ATOMIC_P(NODE)				\
+   ((cp_type_quals (NODE) & TYPE_QUAL_ATOMIC) != 0)
+ 
  /* Nonzero if this type is restrict-qualified.  */
  #define CP_TYPE_RESTRICT_P(NODE)			\
    ((cp_type_quals (NODE) & TYPE_QUAL_RESTRICT) != 0)
*************** typedef enum cp_decl_spec {
*** 4758,4763 ****
--- 4762,4768 ----
    ds_const,
    ds_volatile,
    ds_restrict,
+   ds_atomic,
    ds_inline,
    ds_virtual,
    ds_explicit,
Index: gcc/cp/class.c
===================================================================
*** gcc/cp/class.c	(revision 201248)
--- gcc/cp/class.c	(working copy)
*************** build_simple_base_path (tree expr, tree
*** 542,548 ****
  	   to mark the expression itself.  */
  	if (type_quals & TYPE_QUAL_CONST)
  	  TREE_READONLY (expr) = 1;
! 	if (type_quals & TYPE_QUAL_VOLATILE)
  	  TREE_THIS_VOLATILE (expr) = 1;
  
  	return expr;
--- 542,548 ----
  	   to mark the expression itself.  */
  	if (type_quals & TYPE_QUAL_CONST)
  	  TREE_READONLY (expr) = 1;
! 	if (type_quals & (TYPE_QUAL_VOLATILE|TYPE_QUAL_ATOMIC))
  	  TREE_THIS_VOLATILE (expr) = 1;
  
  	return expr;
Index: gcc/cp/cvt.c
===================================================================
*** gcc/cp/cvt.c	(revision 201248)
--- gcc/cp/cvt.c	(working copy)
*************** diagnose_ref_binding (location_t loc, tr
*** 385,390 ****
--- 385,396 ----
        else if (CP_TYPE_VOLATILE_P (ttl))
  	msg = G_("conversion to volatile reference type %q#T "
  	         "from rvalue of type %qT");
+       else if (CP_TYPE_ATOMIC_P (ttl) && decl)
+ 	msg = G_("initialization of atomic reference type %q#T from "
+ 	         "rvalue of type %qT");
+       else if (CP_TYPE_ATOMIC_P (ttl))
+ 	msg = G_("conversion to atomic reference type %q#T "
+ 	         "from rvalue of type %qT");
        else if (decl)
  	msg = G_("initialization of non-const reference type %q#T from "
  	         "rvalue of type %qT");
*************** convert_from_reference (tree val)
*** 537,543 ****
  	  so that we get the proper error message if the result is used
  	  to assign to.  Also, &* is supposed to be a no-op.  */
        TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
!       TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
        TREE_SIDE_EFFECTS (ref)
  	= (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (val));
        val = ref;
--- 543,550 ----
  	  so that we get the proper error message if the result is used
  	  to assign to.  Also, &* is supposed to be a no-op.  */
        TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
!       TREE_THIS_VOLATILE (ref) = (CP_TYPE_VOLATILE_P (t) 
! 				  || CP_TYPE_ATOMIC_P (t));
        TREE_SIDE_EFFECTS (ref)
  	= (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (val));
        val = ref;
*************** convert_to_void (tree expr, impl_conv_vo
*** 1010,1016 ****
  	tree type = TREE_TYPE (expr);
  	int is_reference = TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0)))
  			   == REFERENCE_TYPE;
! 	int is_volatile = TYPE_VOLATILE (type);
  	int is_complete = COMPLETE_TYPE_P (complete_type (type));
  
  	/* Can't load the value if we don't know the type.  */
--- 1017,1023 ----
  	tree type = TREE_TYPE (expr);
  	int is_reference = TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0)))
  			   == REFERENCE_TYPE;
! 	int is_volatile = (TYPE_VOLATILE (type) || TYPE_ATOMIC (type));
  	int is_complete = COMPLETE_TYPE_P (complete_type (type));
  
  	/* Can't load the value if we don't know the type.  */
*************** convert_to_void (tree expr, impl_conv_vo
*** 1170,1176 ****
  	tree type = TREE_TYPE (expr);
  	int is_complete = COMPLETE_TYPE_P (complete_type (type));
  
! 	if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning))
  	  switch (implicit)
  	    {
  	      case ICV_CAST:
--- 1177,1184 ----
  	tree type = TREE_TYPE (expr);
  	int is_complete = COMPLETE_TYPE_P (complete_type (type));
  
! 	if ((TYPE_VOLATILE (type) || TYPE_ATOMIC (type))
! 	    && !is_complete && (complain & tf_warning))
  	  switch (implicit)
  	    {
  	      case ICV_CAST:
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c	(revision 201248)
--- gcc/cp/decl.c	(working copy)
*************** grokfndecl (tree ctype,
*** 7368,7374 ****
    for (t = parms; t; t = DECL_CHAIN (t))
      DECL_CONTEXT (t) = decl;
    /* Propagate volatile out from type to decl.  */
!   if (TYPE_VOLATILE (type))
      TREE_THIS_VOLATILE (decl) = 1;
  
    /* Setup decl according to sfk.  */
--- 7368,7374 ----
    for (t = parms; t; t = DECL_CHAIN (t))
      DECL_CONTEXT (t) = decl;
    /* Propagate volatile out from type to decl.  */
!   if (TYPE_VOLATILE (type) || TYPE_ATOMIC (type))
      TREE_THIS_VOLATILE (decl) = 1;
  
    /* Setup decl according to sfk.  */
*************** build_ptrmemfunc_type (tree type)
*** 7984,7989 ****
--- 7984,7990 ----
        TYPE_READONLY (t) = (type_quals & TYPE_QUAL_CONST) != 0;
        TYPE_VOLATILE (t) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
        TYPE_RESTRICT (t) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
+       TYPE_ATOMIC (t) = (type_quals & TYPE_QUAL_ATOMIC) != 0;
        TYPE_MAIN_VARIANT (t) = unqualified_variant;
        TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
        TYPE_NEXT_VARIANT (unqualified_variant) = t;
*************** grokdeclarator (const cp_declarator *dec
*** 9199,9204 ****
--- 9200,9207 ----
      type_quals |= TYPE_QUAL_VOLATILE;
    if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
      type_quals |= TYPE_QUAL_RESTRICT;
+   if (decl_spec_seq_has_spec_p (declspecs, ds_atomic))
+     type_quals |= TYPE_QUAL_ATOMIC;
    if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)
      error ("qualifiers are not allowed on declaration of %<operator %T%>",
  	   ctor_return_type);
Index: gcc/cp/mangle.c
===================================================================
*** gcc/cp/mangle.c	(revision 201248)
--- gcc/cp/mangle.c	(working copy)
*************** dump_substitution_candidates (void)
*** 326,331 ****
--- 326,332 ----
        if (TYPE_P (el) &&
  	  (CP_TYPE_RESTRICT_P (el)
  	   || CP_TYPE_VOLATILE_P (el)
+ 	   || CP_TYPE_ATOMIC_P (el)
  	   || CP_TYPE_CONST_P (el)))
  	fprintf (stderr, "CV-");
        fprintf (stderr, "%s (%s at %p)\n",
Index: gcc/cp/parser.c
===================================================================
*** gcc/cp/parser.c	(revision 201248)
--- gcc/cp/parser.c	(working copy)
*************** cp_parser_type_specifier (cp_parser* par
*** 14090,14095 ****
--- 14090,14103 ----
  	*is_cv_qualifier = true;
        break;
  
+     case RID_ATOMIC:
+       ds = ds_atomic;
+       if (is_cv_qualifier)
+ 	*is_cv_qualifier = true;
+       if (!flag_isoc11)
+         pedwarn (token->location, 0, "_Atomic qualifier provided in ISO C11");
+       break;
+ 
      case RID_RESTRICT:
        ds = ds_restrict;
        if (is_cv_qualifier)
*************** cp_parser_cv_qualifier_seq_opt (cp_parse
*** 17341,17346 ****
--- 17349,17358 ----
  	  cv_qualifier = TYPE_QUAL_RESTRICT;
  	  break;
  
+ 	case RID_ATOMIC:
+ 	  cv_qualifier = TYPE_QUAL_ATOMIC;
+ 	  break;
+ 
  	default:
  	  cv_qualifier = TYPE_UNQUALIFIED;
  	  break;
*************** set_and_check_decl_spec_loc (cp_decl_spe
*** 23477,23482 ****
--- 23489,23495 ----
  	    "const",
  	    "volatile",
  	    "restrict",
+ 	    "atomic"
  	    "inline",
  	    "virtual",
  	    "explicit",
Index: gcc/cp/pt.c
===================================================================
*** gcc/cp/pt.c	(revision 201248)
--- gcc/cp/pt.c	(working copy)
*************** check_cv_quals_for_unify (int strict, tr
*** 16375,16381 ****
        if ((TREE_CODE (arg) == REFERENCE_TYPE
  	   || TREE_CODE (arg) == FUNCTION_TYPE
  	   || TREE_CODE (arg) == METHOD_TYPE)
! 	  && (parm_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)))
  	return 0;
  
        if ((!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
--- 16375,16382 ----
        if ((TREE_CODE (arg) == REFERENCE_TYPE
  	   || TREE_CODE (arg) == FUNCTION_TYPE
  	   || TREE_CODE (arg) == METHOD_TYPE)
! 	  && (parm_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE 
! 			    | TYPE_QUAL_ATOMIC)))
  	return 0;
  
        if ((!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
Index: gcc/cp/rtti.c
===================================================================
*** gcc/cp/rtti.c	(revision 201248)
--- gcc/cp/rtti.c	(working copy)
*************** qualifier_flags (tree type)
*** 808,813 ****
--- 808,815 ----
      flags |= 2;
    if (quals & TYPE_QUAL_RESTRICT)
      flags |= 4;
+   if (quals & TYPE_QUAL_ATOMIC)
+     flags |= 8;
    return flags;
  }
  
Index: gcc/cp/semantics.c
===================================================================
*** gcc/cp/semantics.c	(revision 201248)
--- gcc/cp/semantics.c	(working copy)
*************** non_const_var_error (tree r)
*** 7776,7781 ****
--- 7776,7784 ----
        else if (CP_TYPE_VOLATILE_P (type))
  	inform (DECL_SOURCE_LOCATION (r),
  		"%q#D is volatile", r);
+       else if (CP_TYPE_ATOMIC_P (type))
+ 	inform (DECL_SOURCE_LOCATION (r),
+ 		"%q#D is atomic", r);
        else if (!DECL_INITIAL (r)
  	       || !TREE_CONSTANT (DECL_INITIAL (r)))
  	inform (DECL_SOURCE_LOCATION (r),
Index: gcc/cp/tree.c
===================================================================
*** gcc/cp/tree.c	(revision 201248)
--- gcc/cp/tree.c	(working copy)
*************** cp_build_qualified_type_real (tree type,
*** 1059,1072 ****
    /* A reference or method type shall not be cv-qualified.
       [dcl.ref], [dcl.fct].  This used to be an error, but as of DR 295
       (in CD1) we always ignore extra cv-quals on functions.  */
!   if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
        && (TREE_CODE (type) == REFERENCE_TYPE
  	  || TREE_CODE (type) == FUNCTION_TYPE
  	  || TREE_CODE (type) == METHOD_TYPE))
      {
        if (TREE_CODE (type) == REFERENCE_TYPE)
! 	bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
!       type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
      }
  
    /* But preserve any function-cv-quals on a FUNCTION_TYPE.  */
--- 1059,1073 ----
    /* A reference or method type shall not be cv-qualified.
       [dcl.ref], [dcl.fct].  This used to be an error, but as of DR 295
       (in CD1) we always ignore extra cv-quals on functions.  */
!   if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_ATOMIC)
        && (TREE_CODE (type) == REFERENCE_TYPE
  	  || TREE_CODE (type) == FUNCTION_TYPE
  	  || TREE_CODE (type) == METHOD_TYPE))
      {
        if (TREE_CODE (type) == REFERENCE_TYPE)
! 	bad_quals |= type_quals 
! 		    & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_ATOMIC);
!       type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_ATOMIC);
      }
  
    /* But preserve any function-cv-quals on a FUNCTION_TYPE.  */
*************** cv_unqualified (tree type)
*** 1142,1148 ****
      return type;
  
    quals = cp_type_quals (type);
!   quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
    return cp_build_qualified_type (type, quals);
  }
  
--- 1143,1149 ----
      return type;
  
    quals = cp_type_quals (type);
!   quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE|TYPE_QUAL_ATOMIC);
    return cp_build_qualified_type (type, quals);
  }
  
Index: gcc/cp/typeck.c
===================================================================
*** gcc/cp/typeck.c	(revision 201248)
--- gcc/cp/typeck.c	(working copy)
*************** build_class_member_access_expr (tree obj
*** 2417,2423 ****
  	 expression itself.  */
        if (type_quals & TYPE_QUAL_CONST)
  	TREE_READONLY (result) = 1;
!       if (type_quals & TYPE_QUAL_VOLATILE)
  	TREE_THIS_VOLATILE (result) = 1;
      }
    else if (BASELINK_P (member))
--- 2417,2423 ----
  	 expression itself.  */
        if (type_quals & TYPE_QUAL_CONST)
  	TREE_READONLY (result) = 1;
!       if (type_quals & (TYPE_QUAL_VOLATILE|TYPE_QUAL_ATOMIC))
  	TREE_THIS_VOLATILE (result) = 1;
      }
    else if (BASELINK_P (member))
*************** cp_build_indirect_ref (tree ptr, ref_ope
*** 2941,2947 ****
  	     so that we get the proper error message if the result is used
  	     to assign to.  Also, &* is supposed to be a no-op.  */
  	  TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
! 	  TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
  	  TREE_SIDE_EFFECTS (ref)
  	    = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
  	  return ref;
--- 2941,2948 ----
  	     so that we get the proper error message if the result is used
  	     to assign to.  Also, &* is supposed to be a no-op.  */
  	  TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
! 	  TREE_THIS_VOLATILE (ref) = (CP_TYPE_VOLATILE_P (t) 
! 				      || CP_TYPE_ATOMIC_P (t));
  	  TREE_SIDE_EFFECTS (ref)
  	    = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
  	  return ref;
*************** cp_build_array_ref (location_t loc, tree
*** 3126,3134 ****
        TREE_READONLY (rval)
  	|= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
        TREE_SIDE_EFFECTS (rval)
! 	|= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
        TREE_THIS_VOLATILE (rval)
! 	|= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
        ret = require_complete_type_sfinae (fold_if_not_in_template (rval),
  					  complain);
        protected_set_expr_location (ret, loc);
--- 3127,3137 ----
        TREE_READONLY (rval)
  	|= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
        TREE_SIDE_EFFECTS (rval)
! 	|= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array)
! 	    | CP_TYPE_ATOMIC_P (type));
        TREE_THIS_VOLATILE (rval)
! 	|= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array)
! 	    | CP_TYPE_ATOMIC_P (type));
        ret = require_complete_type_sfinae (fold_if_not_in_template (rval),
  					  complain);
        protected_set_expr_location (ret, loc);
*************** check_return_expr (tree retval, bool *no
*** 8423,8429 ****
       && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
                       (TYPE_MAIN_VARIANT (functype)))
       /* And the returned value must be non-volatile.  */
!      && ! TYPE_VOLATILE (TREE_TYPE (retval)));
       
    if (fn_returns_value_p && flag_elide_constructors)
      {
--- 8426,8433 ----
       && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
                       (TYPE_MAIN_VARIANT (functype)))
       /* And the returned value must be non-volatile.  */
!      && ! TYPE_VOLATILE (TREE_TYPE (retval)) 
!      && ! TYPE_ATOMIC (TREE_TYPE (retval)));
       
    if (fn_returns_value_p && flag_elide_constructors)
      {
*************** cp_type_quals (const_tree type)
*** 8691,8697 ****
    /* METHOD and REFERENCE_TYPEs should never have quals.  */
    gcc_assert ((TREE_CODE (type) != METHOD_TYPE
  	       && TREE_CODE (type) != REFERENCE_TYPE)
! 	      || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
  		  == TYPE_UNQUALIFIED));
    return quals;
  }
--- 8695,8701 ----
    /* METHOD and REFERENCE_TYPEs should never have quals.  */
    gcc_assert ((TREE_CODE (type) != METHOD_TYPE
  	       && TREE_CODE (type) != REFERENCE_TYPE)
! 	    || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE|TYPE_QUAL_ATOMIC))
  		  == TYPE_UNQUALIFIED));
    return quals;
  }
*************** bool
*** 8751,8757 ****
  cv_qualified_p (const_tree type)
  {
    int quals = cp_type_quals (type);
!   return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
  }
  
  /* Returns nonzero if the TYPE contains a mutable member.  */
--- 8755,8761 ----
  cv_qualified_p (const_tree type)
  {
    int quals = cp_type_quals (type);
!   return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE|TYPE_QUAL_ATOMIC)) != 0;
  }
  
  /* Returns nonzero if the TYPE contains a mutable member.  */
Index: gcc/doc/generic.texi
===================================================================
*** gcc/doc/generic.texi	(revision 201248)
--- gcc/doc/generic.texi	(working copy)
*************** This macro holds if the type is @code{co
*** 2547,2552 ****
--- 2547,2555 ----
  @item CP_TYPE_VOLATILE_P
  This macro holds if the type is @code{volatile}-qualified.
  
+ @item CP_TYPE_ATOMIC_P
+ This macro holds if the type is @code{atomic}-qualified.
+ 
  @item CP_TYPE_RESTRICT_P
  This macro holds if the type is @code{restrict}-qualified.
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]