summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Builtins.def1
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp5
-rw-r--r--clang/lib/Sema/SemaChecking.cpp1
-rw-r--r--clang/test/Sema/MicrosoftExtensions.c14
4 files changed, 20 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index 53bec2ab83a..540ec25bad4 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -681,6 +681,7 @@ LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "v.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c105d80bf79..b0e63b647d8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -215,8 +215,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0));
case Builtin::BI__builtin_stdarg_start:
case Builtin::BI__builtin_va_start:
+ case Builtin::BI__va_start:
case Builtin::BI__builtin_va_end: {
- Value *ArgValue = EmitVAListRef(E->getArg(0));
+ Value *ArgValue = (BuiltinID == Builtin::BI__va_start)
+ ? EmitScalarExpr(E->getArg(0))
+ : EmitVAListRef(E->getArg(0));
llvm::Type *DestType = Int8PtrTy;
if (ArgValue->getType() != DestType)
ArgValue = Builder.CreateBitCast(ArgValue, DestType,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 02852313056..f0e93a78f75 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -142,6 +142,7 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
break;
case Builtin::BI__builtin_stdarg_start:
case Builtin::BI__builtin_va_start:
+ case Builtin::BI__va_start:
if (SemaBuiltinVAStart(TheCall))
return ExprError();
break;
diff --git a/clang/test/Sema/MicrosoftExtensions.c b/clang/test/Sema/MicrosoftExtensions.c
index 4441f179736..a4afcb1e640 100644
--- a/clang/test/Sema/MicrosoftExtensions.c
+++ b/clang/test/Sema/MicrosoftExtensions.c
@@ -131,3 +131,17 @@ int *(__ptr32 __sptr wrong9); // expected-error {{'__sptr' attribute only applie
typedef int *T;
T __ptr32 wrong10; // expected-error {{'__ptr32' attribute only applies to pointer arguments}}
+
+typedef char *my_va_list;
+void __cdecl __va_start(my_va_list *ap, ...); // expected-note {{passing argument to parameter 'ap' here}}
+void vmyprintf(const char *f, my_va_list ap);
+void myprintf(const char *f, ...) {
+ my_va_list ap;
+ if (1) {
+ __va_start(&ap, f);
+ vmyprintf(f, ap);
+ ap = 0;
+ } else {
+ __va_start(ap, f); // expected-warning {{incompatible pointer types passing 'my_va_list'}}
+ }
+}
OpenPOWER on IntegriCloud