Index: clang/include/clang/AST/ExprCXX.h =================================================================== --- clang/include/clang/AST/ExprCXX.h +++ clang/include/clang/AST/ExprCXX.h @@ -2261,15 +2261,32 @@ bool isArray() const { return CXXNewExprBits.IsArray; } + /// This might return None even if isArray() returns true, + /// since there might not be an array size expression. + /// If the result is not-None, it will never wrap a nullptr. Optional getArraySize() { if (!isArray()) return None; - return cast_or_null(getTrailingObjects()[arraySizeOffset()]); + + if (auto *Result = + cast_or_null(getTrailingObjects()[arraySizeOffset()])) + return Result; + + return None; } + + /// This might return None even if isArray() returns true, + /// since there might not be an array size expression. + /// If the result is not-None, it will never wrap a nullptr. Optional getArraySize() const { if (!isArray()) return None; - return cast_or_null(getTrailingObjects()[arraySizeOffset()]); + + if (auto *Result = + cast_or_null(getTrailingObjects()[arraySizeOffset()])) + return Result; + + return None; } unsigned getNumPlacementArgs() const { Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -9427,7 +9427,7 @@ bool ValueInit = false; QualType AllocType = E->getAllocatedType(); - if (Optional ArraySize = E->getArraySize()) { + if (Optional ArraySize = E->getArraySize()) { const Expr *Stripped = *ArraySize; for (; auto *ICE = dyn_cast(Stripped); Stripped = ICE->getSubExpr()) Index: clang/lib/AST/StmtPrinter.cpp =================================================================== --- clang/lib/AST/StmtPrinter.cpp +++ clang/lib/AST/StmtPrinter.cpp @@ -2132,10 +2132,10 @@ if (E->isParenTypeId()) OS << "("; std::string TypeS; - if (Optional Size = E->getArraySize()) { + if (E->isArray()) { llvm::raw_string_ostream s(TypeS); s << '['; - if (*Size) + if (Optional Size = E->getArraySize()) (*Size)->printPretty(s, Helper, Policy); s << ']'; } Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -11918,9 +11918,9 @@ // Transform the size of the array we're allocating (if any). Optional ArraySize; - if (Optional OldArraySize = E->getArraySize()) { + if (E->isArray()) { ExprResult NewArraySize; - if (*OldArraySize) { + if (Optional OldArraySize = E->getArraySize()) { NewArraySize = getDerived().TransformExpr(*OldArraySize); if (NewArraySize.isInvalid()) return ExprError(); Index: clang/test/AST/issue53742.cpp =================================================================== --- /dev/null +++ clang/test/AST/issue53742.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify + +struct Data { + char *a; + char *b; + bool *c; +}; + +int main() { + Data in; + in.a = new char[](); // expected-error {{cannot determine allocated array size from initializer}} + in.c = new bool[100](); + in.b = new char[100](); +}