diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -640,6 +640,7 @@ BUILTIN(__builtin_shufflevector, "v." , "nct") BUILTIN(__builtin_convertvector, "v." , "nct") BUILTIN(__builtin_alloca, "v*z" , "Fn") +BUILTIN(__builtin_alloca_uninitialized, "v*z", "Fn") BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn") BUILTIN(__builtin_call_with_static_chain, "v.", "nt") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3417,6 +3417,7 @@ case Builtin::BIalloca: case Builtin::BI_alloca: + case Builtin::BI__builtin_alloca_uninitialized: case Builtin::BI__builtin_alloca: { Value *Size = EmitScalarExpr(E->getArg(0)); const TargetInfo &TI = getContext().getTargetInfo(); @@ -3427,7 +3428,8 @@ .getAsAlign(); AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); AI->setAlignment(SuitableAlignmentInBytes); - initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); + if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) + initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); return RValue::get(AI); } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1686,6 +1686,7 @@ if (SemaBuiltinAllocaWithAlign(TheCall)) return ExprError(); LLVM_FALLTHROUGH; + case Builtin::BI__builtin_alloca_uninitialized: case Builtin::BI__builtin_alloca: Diag(TheCall->getBeginLoc(), diag::warn_alloca) << TheCall->getDirectCallee(); diff --git a/clang/test/CodeGenCXX/trivial-auto-var-init.cpp b/clang/test/CodeGenCXX/trivial-auto-var-init.cpp --- a/clang/test/CodeGenCXX/trivial-auto-var-init.cpp +++ b/clang/test/CodeGenCXX/trivial-auto-var-init.cpp @@ -201,6 +201,20 @@ used(ptr); } +// UNINIT-LABEL: test_alloca_uninitialized( +// ZERO-LABEL: test_alloca_uninitialized( +// ZERO: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64 +// ZERO-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]] +// ZERO-NOT: call void @llvm.memset +// PATTERN-LABEL: test_alloca_uninitialized( +// PATTERN: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64 +// PATTERN-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]] +// PATTERN-NOT: call void @llvm.memset +void test_alloca_uninitialized(int size) { + void *ptr = __builtin_alloca_uninitialized(size); + used(ptr); +} + // UNINIT-LABEL: test_struct_vla( // ZERO-LABEL: test_struct_vla( // ZERO: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16 diff --git a/clang/test/Sema/warn-alloca.c b/clang/test/Sema/warn-alloca.c --- a/clang/test/Sema/warn-alloca.c +++ b/clang/test/Sema/warn-alloca.c @@ -18,3 +18,10 @@ // expected-warning@-2 {{use of function '__builtin_alloca_with_align' is discouraged; there is no way to check for failure but failure may still occur, resulting in a possibly exploitable security vulnerability}} #endif } + +void test3(int a) { + __builtin_alloca_uninitialized(a); +#ifndef SILENCE + // expected-warning@-2 {{use of function '__builtin_alloca_uninitialized' is discouraged; there is no way to check for failure but failure may still occur, resulting in a possibly exploitable security vulnerability}} +#endif +}