aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaChecking.cpp27
-rw-r--r--test/CodeGen/atomic.c5
-rw-r--r--test/Sema/builtins.c2
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}}
}