Joseph,

this fixes the remaining issue related to PR120510.  It is
related to this GNU extenions:
https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Function-Prototypes.html#Function-Prototypes

Here I simply override the type with the one with the prototype.
This is not a perfect replacement for forming the composite type,
but I assume this does not matter for any existing code.  But if
you think it is better to keep forming the composite type, an
alternative could be to add a flag to comptypes to ignore thisĀ 
special case only in this specific scenario.


Bootstrapped and regression tested for x86_64.


    c: remaining fix for the composite type inconsistency [PR120510]
    
    There is an old GNU extension which allows overriding the
    promoted old-style arguments when there is an earlier prototype
    An example (from a test added for PR16666) is the following.
    
    float dremf (float, float);
    
    float
    dremf (x, y)
         float x, y;
    {
      return x + y;
    }
    
    The types of the two declarations are not compatible, because
    the arguments are not self-promoting.  Instead of forming a composite
    type, we simply copy the type from the earlier prototype.
    
    gcc/c/ChangeLog:
            * c-typeck.cc (composite_type_internal): Activate checking
            assertions for all types and also inputs.
            * c-decl.cc (start_function): Call composite_type only
            for compatible function types.

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 2b0bd663ba9..1c86c01269f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -10715,7 +10715,10 @@ start_function (struct c_declspecs *declspecs, struct 
c_declarator *declarator,
                          "without prototype", decl1);
              locate_old_decl (old_decl);
            }
-         TREE_TYPE (decl1) = composite_type (oldtype, newtype);
+         if (comptypes (oldtype, newtype))
+           TREE_TYPE (decl1) = composite_type (oldtype, newtype);
+         else
+           TREE_TYPE (decl1) = oldtype;
          current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
          current_function_prototype_built_in
            = C_DECL_BUILTIN_PROTOTYPE (old_decl);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index ae3e7068729..28a80cd2636 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -1002,15 +1002,13 @@ composite_type_internal (tree t1, tree t2, struct 
composite_cache* cache)
 tree
 composite_type (tree t1, tree t2)
 {
+  gcc_checking_assert (comptypes (t1, t2));
+
   struct composite_cache cache = { };
   tree n = composite_type_internal (t1, t2, &cache);
-  /* For function types there are some cases where qualifiers do
-     not match.  See PR120510.  */
-  if (FUNCTION_TYPE != TREE_CODE (n))
-    {
-      gcc_checking_assert (comptypes (n, t1));
-      gcc_checking_assert (comptypes (n, t2));
-    }
+
+  gcc_checking_assert (comptypes (n, t1));
+  gcc_checking_assert (comptypes (n, t2));
   return n;
 }
 

Reply via email to