diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -14460,8 +14460,10 @@ const Expr *E, llvm::APSInt *Value, SourceLocation *Loc) { - if (!E->getType()->isIntegralOrUnscopedEnumerationType()) { - if (Loc) *Loc = E->getExprLoc(); + if (!E->getType()->isIntegralOrUnscopedEnumerationType() && + !E->getType()->isAlignValT()) { + if (Loc) + *Loc = E->getExprLoc(); return false; } @@ -14593,7 +14595,8 @@ ArgVector ArgValues(Args.size()); for (ArrayRef::iterator I = Args.begin(), E = Args.end(); I != E; ++I) { - if ((*I)->isValueDependent() || + // Arg can be null in malformed code. + if (!*I || (*I)->isValueDependent() || !Evaluate(ArgValues[I - Args.begin()], Info, *I) || Info.EvalStatus.HasSideEffects) // If evaluation fails, throw away the argument entirely. 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 @@ -4476,7 +4476,7 @@ if (FDecl && FDecl->hasAttr()) { auto *AA = FDecl->getAttr(); const Expr *Arg = Args[AA->getParamIndex().getASTIndex()]; - if (!Arg->isTypeDependent() && !Arg->isValueDependent()) { + if (Arg && !Arg->isTypeDependent() && !Arg->isValueDependent()) { llvm::APSInt I(64); if (Arg->isIntegerConstantExpr(I, Context)) { if (!I.isPowerOf2()) { diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2078,10 +2078,15 @@ if (!AllPlaceArgs.empty()) PlacementArgs = AllPlaceArgs; - // FIXME: This is wrong: PlacementArgs misses out the first (size) argument. - DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs); + llvm::SmallVector CallArgs; + CallArgs.reserve(1 + PlacementArgs.size()); + CallArgs.emplace_back(nullptr); // FIXME: size argument. + CallArgs.insert(CallArgs.end(), PlacementArgs.begin(), PlacementArgs.end()); - // FIXME: Missing call to CheckFunctionCall or equivalent + DiagnoseSentinelCalls(OperatorNew, PlacementLParen, CallArgs); + + checkCall(OperatorNew, Proto, /*ThisArg=*/nullptr, CallArgs, + /*IsMemberFunction=*/false, StartLoc, Range, CallType); // Warn if the type is over-aligned and is being allocated by (unaligned) // global operator new. diff --git a/clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp b/clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp --- a/clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp +++ b/clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp @@ -30,10 +30,8 @@ void *ptr_variable(int align) { return new (std::align_val_t(align)) A; } void *ptr_align16() { return new (std::align_val_t(16)) A; } -void *ptr_align15() { return new (std::align_val_t(15)) A; } +void *ptr_align15() { return new (std::align_val_t(15)) A; } // expected-error {{requested alignment is not a power of 2}} std::align_val_t align_variable(int align) { return std::align_val_t(align); } std::align_val_t align_align16() { return std::align_val_t(16); } std::align_val_t align_align15() { return std::align_val_t(15); } - -// expected-no-diagnostics