Stop trying to fixup 'overloadable' prototypeless functions.
authorErich Keane <erich.keane@intel.com>
Thu, 15 Sep 2022 19:07:23 +0000 (12:07 -0700)
committerErich Keane <erich.keane@intel.com>
Thu, 15 Sep 2022 19:10:54 +0000 (12:10 -0700)
While investigating something else, I discovered that a prototypeless
function with 'overloadable' was having the attribute left on the
declaration, which caused 'ambiguous' call errors later on. This lead to
some confusion.  This patch removes the 'overloadable' attribute from
the declaration and leaves it as prototypeless, instead of trying to
make it variadic.

clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDecl.cpp
clang/test/Sema/overloadable.c

index 0680aa5..f897c68 100644 (file)
@@ -119,6 +119,9 @@ Bug Fixes
   `Issue 57169 <https://github.com/llvm/llvm-project/issues/57169>`_
 - Clang configuration files are now read through the virtual file system
   rather than the physical one, if these are different.
+- Clang will now no longer treat a C 'overloadable' function without a prototype as
+  a variadic function with the attribute.  This should make further diagnostics more
+  clear.
 
 
 Improvements to Clang's diagnostics
index e4bd827..d1e1d8a 100644 (file)
@@ -10372,16 +10372,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     Diag(NewFD->getLocation(),
          diag::err_attribute_overloadable_no_prototype)
       << NewFD;
-
-    // Turn this into a variadic function with no parameters.
-    const auto *FT = NewFD->getType()->castAs<FunctionType>();
-    FunctionProtoType::ExtProtoInfo EPI(
-        Context.getDefaultCallingConvention(true, false));
-    EPI.Variadic = true;
-    EPI.ExtInfo = FT->getExtInfo();
-
-    QualType R = Context.getFunctionType(FT->getReturnType(), None, EPI);
-    NewFD->setType(R);
+    NewFD->dropAttr<OverloadableAttr>();
   }
 
   // If there's a #pragma GCC visibility in scope, and this isn't a class
index ebd9ad1..42d04a5 100644 (file)
@@ -74,6 +74,16 @@ void test() {
   f1();
 }
 
+// Validate that the invalid function doesn't stay overloadable. 
+int __attribute__((overloadable)) invalid(); // expected-error{{'overloadable' function 'invalid' must have a prototype}}
+int __attribute__((overloadable)) invalid(int); // expected-error{{redeclaration of 'invalid' must not have the 'overloadable' attribute}}
+                                                // expected-note@-2{{previous unmarked overload of function is here}}
+void use_invalid(void) {
+  invalid(); // expected-error{{too few arguments to function call, expected 1, have 0}}
+             // expected-note@-4{{'invalid' declared here}}
+  invalid(1);
+}
+
 void before_local_1(int) __attribute__((overloadable));
 void before_local_2(int); // expected-note {{here}}
 void before_local_3(int) __attribute__((overloadable));