diff options
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 27 | ||||
-rw-r--r-- | test/CodeGen/atomic.c | 5 | ||||
-rw-r--r-- | test/Sema/builtins.c | 2 |
3 files changed, 24 insertions, 10 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index e8b908ed3f..edb5a49466 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -293,6 +293,25 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) << 0 << TheCall->getCallee()->getSourceRange(); + + // Get the decl for the concrete builtin from this, we can tell what the + // 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())); + const FunctionProtoType *BuiltinFT = + NewBuiltinDecl->getType()->getAsFunctionProtoType(); + ValType = BuiltinFT->getArgType(0)->getAsPointerType()->getPointeeType(); + + // If the first type needs to be converted (e.g. void** -> int*), do it now. + if (BuiltinFT->getArgType(0) != FirstArg->getType()) { + ImpCastExprToType(FirstArg, BuiltinFT->getArgType(0), false); + TheCall->setArg(0, FirstArg); + } + // Next, walk the valid ones promoting to the right type. for (unsigned i = 0; i != NumFixed; ++i) { Expr *Arg = TheCall->getArg(i+1); @@ -321,14 +340,6 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { TheCall->setArg(i+1, Arg); } - // Okay, if we get here, everything is good. Get the decl for the concrete - // builtin. - 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())); // Switch the DeclRefExpr to refer to the new decl. DRE->setDecl(NewBuiltinDecl); DRE->setType(NewBuiltinDecl->getType()); diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c index c224cbdeba..0e7af23f7a 100644 --- a/test/CodeGen/atomic.c +++ b/test/CodeGen/atomic.c @@ -6,7 +6,7 @@ // RUN: grep @llvm.atomic.load.umin.i32 %t1 && // RUN: grep @llvm.atomic.load.umax.i32 %t1 && // RUN: grep @llvm.atomic.swap.i32 %t1 && -// RUN: grep @llvm.atomic.cmp.swap.i32 %t1 | count 3 && +// RUN: grep @llvm.atomic.cmp.swap.i32 %t1 | count 4 && // RUN: grep @llvm.atomic.load.and.i32 %t1 | count 2 && // RUN: grep @llvm.atomic.load.or.i8 %t1 && // RUN: grep @llvm.atomic.load.xor.i8 %t1 @@ -40,5 +40,8 @@ int atomic(void) old = __sync_or_and_fetch(&valc, 4); old = __sync_xor_and_fetch(&valc, 5); + + __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0); + return old; } diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c index c6ef5ea0d1..e57aec51bc 100644 --- a/test/Sema/builtins.c +++ b/test/Sema/builtins.c @@ -48,5 +48,5 @@ unsigned char test9(short v) { old = __sync_fetch_and_add(); // expected-error {{too few arguments to function call}} old = __sync_fetch_and_add(&old); // expected-error {{too few arguments to function call}} - old = __sync_fetch_and_add((int**)0, 42i); // expected-error {{operand of type '_Complex int' cannot be cast to a pointer type}} expected-warning {{imaginary constants are an extension}} + old = __sync_fetch_and_add((int**)0, 42i); // expected-warning {{imaginary constants are an extension}} } |