tambre updated this revision to Diff 264447.
tambre marked 3 inline comments as done.
tambre added a comment.

Fix adding BuiltinAttr in C++ mode. Update one test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77491/new/

https://reviews.llvm.org/D77491

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/IdentifierTable.h
  clang/lib/AST/Decl.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/AST/ast-dump-attr.cpp
  clang/test/CodeGen/builtin-redeclaration.c
  clang/test/Sema/implicit-builtin-decl.c

Index: clang/test/Sema/implicit-builtin-decl.c
===================================================================
--- clang/test/Sema/implicit-builtin-decl.c
+++ clang/test/Sema/implicit-builtin-decl.c
@@ -60,12 +60,15 @@
 
 extern float fmaxf(float, float);
 
-struct __jmp_buf_tag {};
-void sigsetjmp(struct __jmp_buf_tag[1], int); // expected-warning{{declaration of built-in function 'sigsetjmp' requires the declaration of the 'jmp_buf' type, commonly provided in the header <setjmp.h>.}}
+typedef struct __jmp_buf_tag {
+} sigjmp_buf[1];
 
-// CHECK:     FunctionDecl {{.*}} <line:[[@LINE-2]]:1, col:44> col:6 sigsetjmp '
+int sigsetjmp(struct __jmp_buf_tag[1], int);
+
+// CHECK:     FunctionDecl {{.*}} <line:[[@LINE-2]]:5> col:5 implicit sigsetjmp '
+// CHECK:     FunctionDecl {{.*}} <col:1, col:43> col:5 sigsetjmp '
 // CHECK-NOT: FunctionDecl
-// CHECK:     ReturnsTwiceAttr {{.*}} <{{.*}}> Implicit
+// CHECK:     ReturnsTwiceAttr {{.*}} <{{.*}}> Inherited Implicit
 
 // PR40692
 void pthread_create(); // no warning expected
Index: clang/test/CodeGen/builtin-redeclaration.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/builtin-redeclaration.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+// PR45410
+// Ensure we mark local extern redeclarations with a different type as non-builtin.
+void non_builtin() {
+  extern float exp();
+  exp(); // Will crash due to wrong number of arguments if this calls the builtin.
+}
+
+// PR45410
+// We mark exp() builtin as const with -fno-math-errno (default).
+// We mustn't do that for extern redeclarations of builtins where the type differs.
+float attribute() {
+  extern float exp();
+  return exp(1);
+}
Index: clang/test/AST/ast-dump-attr.cpp
===================================================================
--- clang/test/AST/ast-dump-attr.cpp
+++ clang/test/AST/ast-dump-attr.cpp
@@ -109,6 +109,7 @@
 extern "C" int printf(const char *format, ...);
 // CHECK: FunctionDecl{{.*}}printf
 // CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *'
+// CHECK-NEXT: BuiltinAttr{{.*}}Implicit
 // CHECK-NEXT: FormatAttr{{.*}}Implicit printf 1 2
 
 alignas(8) extern int x;
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -2108,6 +2108,7 @@
                                            false,
                                            R->isFunctionProtoType());
   New->setImplicit();
+  New->addAttr(BuiltinAttr::CreateImplicit(Context, ID));
 
   // Create Decl objects for each parameter, adding them to the
   // FunctionDecl.
@@ -3330,7 +3331,11 @@
       // there but not here.
       NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
       RequiresAdjustment = true;
-    } else if (New->getBuiltinID()) {
+    } else if (Old->getBuiltinID()) {
+      // Builtin attribute isn't propagated to the new one yet at this point.
+      // Check if the old is a builtin.
+      // TODO: Maybe we should only warn if the redeclaration is compatible?
+
       // Calling Conventions on a Builtin aren't really useful and setting a
       // default calling convention and cdecl'ing some builtin redeclarations is
       // common, so warn and ignore the calling convention on the redeclaration.
@@ -3756,6 +3761,7 @@
   // If the previous declaration was an implicitly-generated builtin
   // declaration, then at the very least we should use a specialized note.
   unsigned BuiltinID;
+  // TODO: Remove isImplicit check?
   if (Old->isImplicit() && (BuiltinID = Old->getBuiltinID())) {
     // If it's actually a library-defined builtin function like 'malloc'
     // or 'printf', just warn about the incompatible redeclaration.
@@ -8859,6 +8865,20 @@
     if (D.isInvalidType())
       NewFD->setInvalidDecl();
 
+    // In C builtins get merged with implicitly lazily created declarations.
+    // In C++ we need to check if it's a builtin and add the BuiltinAttr here.
+    if (IdentifierInfo *II = Previous.getLookupName().getAsIdentifierInfo()) {
+      if (II->getBuiltinID()) {
+        // A builtin needs to have C linkage.
+        LinkageSpecDecl *linkage =
+            dyn_cast<LinkageSpecDecl>(NewFD->getFirstDecl()->getDeclContext());
+        if (linkage && linkage->getLanguage() == LinkageSpecDecl::lang_c) {
+          NewFD->addAttr(
+              BuiltinAttr::CreateImplicit(Context, II->getBuiltinID()));
+        }
+      }
+    }
+
     // Match up the template parameter lists with the scope specifier, then
     // determine whether we have a template or a template specialization.
     bool Invalid = false;
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -3164,10 +3164,12 @@
   if (const auto *ABAA = getAttr<ArmBuiltinAliasAttr>()) {
     BuiltinID = ABAA->getBuiltinName()->getBuiltinID();
   } else {
-    if (!getIdentifier())
+    const auto *Attr = getAttr<BuiltinAttr>();
+
+    if (!Attr)
       return 0;
 
-    BuiltinID = getIdentifier()->getBuiltinID();
+    BuiltinID = Attr->getID();
   }
 
   if (!BuiltinID)
Index: clang/include/clang/Basic/IdentifierTable.h
===================================================================
--- clang/include/clang/Basic/IdentifierTable.h
+++ clang/include/clang/Basic/IdentifierTable.h
@@ -225,7 +225,7 @@
   }
   void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
 
-  /// True if setNotBuiltin() was called.
+  /// True if revertBuiltin() was called.
   bool hasRevertedBuiltin() const {
     return ObjCOrBuiltinID == tok::NUM_OBJC_KEYWORDS;
   }
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -3440,3 +3440,11 @@
   let Subjects = SubjectList<[ParmVar]>;
   let Documentation = [ReleaseHandleDocs];
 }
+
+def Builtin : InheritableAttr {
+  let Spellings = [];
+  let Args = [UnsignedArgument<"ID">];
+  let Subjects = SubjectList<[Function]>;
+  let SemaHandler = 0;
+  let Documentation = [Undocumented];
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to