]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/c-family/c-common.cc
c-family: Cast __atomic_load_*/__atomic_exchange_* result to _BitInt rather then...
[thirdparty/gcc.git] / gcc / c-family / c-common.cc
index b2b70c993388d186ab6b3b78b85fe0333b62b5e0..6fa8243b02b5eda3c427cc210c58e3ed677d8460 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines shared by all languages that are variants of C.
-   Copyright (C) 1992-2023 Free Software Foundation, Inc.
+   Copyright (C) 1992-2024 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -560,13 +560,6 @@ const struct c_common_resword c_common_reswords[] =
   { "wchar_t",         RID_WCHAR,      D_CXXONLY },
   { "while",           RID_WHILE,      0 },
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  { NAME,              RID_##CODE,     D_CXXONLY },
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-  /* An alias for __is_same.  */
-  { "__is_same_as",    RID_IS_SAME,    D_CXXONLY },
-
   /* C++ transactional memory.  */
   { "synchronized",    RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
   { "atomic_noexcept", RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
@@ -2362,6 +2355,15 @@ c_common_type_for_size (unsigned int bits, int unsignedp)
     return (unsignedp ? widest_unsigned_literal_type_node
            : widest_integer_literal_type_node);
 
+  for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t))
+    {
+      tree type = TREE_VALUE (t);
+      if (TREE_CODE (type) == INTEGER_TYPE
+         && bits == TYPE_PRECISION (type)
+         && !!unsignedp == !!TYPE_UNSIGNED (type))
+       return type;
+    }
+
   if (bits <= TYPE_PRECISION (intQI_type_node))
     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
 
@@ -7635,7 +7637,7 @@ get_atomic_generic_size (location_t loc, tree function,
                return 0;
              }
            else
-             pedwarn (loc, OPT_Wincompatible_pointer_types, "argument %d "
+             pedwarn (loc, OPT_Wdiscarded_qualifiers, "argument %d "
                       "of %qE discards %<const%> qualifier", x + 1,
                       function);
          }
@@ -7649,7 +7651,7 @@ get_atomic_generic_size (location_t loc, tree function,
                return 0;
              }
            else
-             pedwarn (loc, OPT_Wincompatible_pointer_types, "argument %d "
+             pedwarn (loc, OPT_Wdiscarded_qualifiers, "argument %d "
                       "of %qE discards %<volatile%> qualifier", x + 1,
                       function);
          }
@@ -7791,9 +7793,14 @@ resolve_overloaded_atomic_exchange (location_t loc, tree function,
   /* Convert object pointer to required type.  */
   p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
   (*params)[0] = p0; 
-  /* Convert new value to required type, and dereference it.  */
-  p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR);
-  p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1);
+  /* Convert new value to required type, and dereference it.
+     If *p1 type can have padding or may involve floating point which
+     could e.g. be promoted to wider precision and demoted afterwards,
+     state of padding bits might not be preserved.  */
+  build_indirect_ref (loc, p1, RO_UNARY_STAR);
+  p1 = build2_loc (loc, MEM_REF, I_type,
+                  build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1),
+                  build_zero_cst (TREE_TYPE (p1)));
   (*params)[1] = p1;
 
   /* Move memory model to the 3rd position, and end param list.  */
@@ -7871,9 +7878,14 @@ resolve_overloaded_atomic_compare_exchange (location_t loc, tree function,
   p1 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1);
   (*params)[1] = p1;
 
-  /* Convert desired value to required type, and dereference it.  */
-  p2 = build_indirect_ref (loc, p2, RO_UNARY_STAR);
-  p2 = build1 (VIEW_CONVERT_EXPR, I_type, p2);
+  /* Convert desired value to required type, and dereference it.
+     If *p2 type can have padding or may involve floating point which
+     could e.g. be promoted to wider precision and demoted afterwards,
+     state of padding bits might not be preserved.  */
+  build_indirect_ref (loc, p2, RO_UNARY_STAR);
+  p2 = build2_loc (loc, MEM_REF, I_type,
+                  build1 (VIEW_CONVERT_EXPR, I_type_ptr, p2),
+                  build_zero_cst (TREE_TYPE (p2)));
   (*params)[2] = p2;
 
   /* The rest of the parameters are fine. NULL means no special return value
@@ -8080,6 +8092,12 @@ atomic_bitint_fetch_using_cas_loop (location_t loc,
   tree lhs_addr = (*orig_params)[0];
   tree val = convert (nonatomic_lhs_type, (*orig_params)[1]);
   tree model = convert (integer_type_node, (*orig_params)[2]);
+  if (!c_dialect_cxx ())
+    {
+      lhs_addr = c_fully_fold (lhs_addr, false, NULL);
+      val = c_fully_fold (val, false, NULL);
+      model = c_fully_fold (model, false, NULL);
+    }
   if (TREE_SIDE_EFFECTS (lhs_addr))
     {
       tree var = create_tmp_var_raw (TREE_TYPE (lhs_addr));
@@ -8443,7 +8461,19 @@ resolve_overloaded_builtin (location_t loc, tree function,
        if (new_return)
          {
            /* Cast function result from I{1,2,4,8,16} to the required type.  */
-           result = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (new_return), result);
+           if (TREE_CODE (TREE_TYPE (new_return)) == BITINT_TYPE)
+             {
+               struct bitint_info info;
+               unsigned prec = TYPE_PRECISION (TREE_TYPE (new_return));
+               targetm.c.bitint_type_info (prec, &info);
+               if (!info.extended)
+                 /* For _BitInt which has the padding bits undefined
+                    convert to the _BitInt type rather than VCE to force
+                    zero or sign extension.  */
+                 result = build1 (NOP_EXPR, TREE_TYPE (new_return), result);
+             }
+           result
+             = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (new_return), result);
            result = build2 (MODIFY_EXPR, TREE_TYPE (new_return), new_return,
                             result);
            TREE_SIDE_EFFECTS (result) = 1;