diff options
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 17 | ||||
-rw-r--r-- | clang/test/Sema/builtins.c | 14 |
2 files changed, 27 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e85024fc556..7951a71e4ed 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1198,10 +1198,19 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { // concrete integer type we should convert to is. unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; const char *NewBuiltinName = Context.BuiltinInfo.GetName(NewBuiltinID); - IdentifierInfo *NewBuiltinII = PP.getIdentifierInfo(NewBuiltinName); - FunctionDecl *NewBuiltinDecl = - cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID, - TUScope, false, DRE->getLocStart())); + FunctionDecl *NewBuiltinDecl; + if (NewBuiltinID == BuiltinID) + NewBuiltinDecl = FDecl; + else { + // Perform builtin lookup to avoid redeclaring it. + DeclarationName DN(&Context.Idents.get(NewBuiltinName)); + LookupResult Res(*this, DN, DRE->getLocStart(), LookupOrdinaryName); + LookupName(Res, TUScope, /*AllowBuiltinCreation=*/true); + assert(Res.getFoundDecl()); + NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl()); + if (NewBuiltinDecl == 0) + return ExprError(); + } // The first argument --- the pointer --- has a fixed type; we // deduce the types of the rest of the arguments accordingly. Walk diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c index b8b03677fda..357b7b6aa07 100644 --- a/clang/test/Sema/builtins.c +++ b/clang/test/Sema/builtins.c @@ -51,6 +51,20 @@ void test9(short v) { } } +// overloaded atomics should be declared only once. +void test9_1(volatile int* ptr, int val) { + __sync_fetch_and_add_4(ptr, val); +} +void test9_2(volatile int* ptr, int val) { + __sync_fetch_and_add(ptr, val); +} +void test9_3(volatile int* ptr, int val) { + __sync_fetch_and_add_4(ptr, val); + __sync_fetch_and_add(ptr, val); + __sync_fetch_and_add(ptr, val); + __sync_fetch_and_add_4(ptr, val); + __sync_fetch_and_add_4(ptr, val); +} // rdar://7236819 void test10(void) __attribute__((noreturn)); |