llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> We failed to check for null and non-block pointers. Fixes https://github.com/llvm/llvm-project/issues/152952 --- Full diff: https://github.com/llvm/llvm-project/pull/164804.diff 4 Files Affected: - (modified) clang/lib/AST/ByteCode/Compiler.cpp (+1-4) - (modified) clang/lib/AST/ByteCode/Interp.cpp (+7) - (modified) clang/lib/AST/ByteCode/Opcodes.td (+2-8) - (modified) clang/test/AST/ByteCode/placement-new.cpp (+29) ``````````diff diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 6b989276e6d7d..228c6f4b11804 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -3600,8 +3600,6 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) { if (PlacementDest) { if (!this->visit(PlacementDest)) return false; - if (!this->emitStartLifetime(E)) - return false; if (!this->emitGetLocal(SizeT, ArrayLen, E)) return false; if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E)) @@ -3741,10 +3739,9 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) { if (PlacementDest) { if (!this->visit(PlacementDest)) return false; - if (!this->emitStartLifetime(E)) - return false; if (!this->emitCheckNewTypeMismatch(E, E)) return false; + } else { // Allocate just one element. if (!this->emitAlloc(Desc, E)) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index a72282caf5e73..939eefc8d2b67 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1903,9 +1903,16 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E, if (Ptr.inUnion() && Ptr.getBase().getRecord()->isUnion()) Ptr.activate(); + if (Ptr.isZero()) { + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_null) + << AK_Construct; + return false; + } + if (!Ptr.isBlockPointer()) return false; + startLifetimeRecurse(Ptr); // Similar to CheckStore(), but with the additional CheckTemporary() call and // the AccessKinds are different. diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 532c4448e6f40..cc52e06d031a2 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -853,19 +853,13 @@ def Free : Opcode { let Args = [ArgBool, ArgBool]; } -def CheckNewTypeMismatch : Opcode { - let Args = [ArgExpr]; -} - -def InvalidNewDeleteExpr : Opcode { - let Args = [ArgExpr]; -} - +def CheckNewTypeMismatch : Opcode { let Args = [ArgExpr]; } def CheckNewTypeMismatchArray : Opcode { let Types = [IntegerTypeClass]; let Args = [ArgExpr]; let HasGroup = 1; } +def InvalidNewDeleteExpr : Opcode { let Args = [ArgExpr]; } def IsConstantContext: Opcode; def CheckAllocations : Opcode; diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp index b587cd6eaf89c..1c015da7be54f 100644 --- a/clang/test/AST/ByteCode/placement-new.cpp +++ b/clang/test/AST/ByteCode/placement-new.cpp @@ -494,3 +494,32 @@ constexpr int modify_const_variable() { } static_assert(modify_const_variable()); // both-error {{not an integral constant expression}} \ // both-note {{in call to}} + +constexpr int nullDest() { + new (nullptr) int{12}; // both-note {{construction of dereferenced null pointer}} + return 0; +} +static_assert(nullDest() == 0); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + +constexpr int nullArrayDest() { + new (nullptr) int{12}; // both-note {{construction of dereferenced null pointer}} + return 0; +} +static_assert(nullArrayDest() == 0); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + +constexpr int intDest() { + new ((void*)2) int{3}; // both-note {{cast that performs the conversions of a reinterpret_cast}} + return 0; +} +static_assert(intDest() == 0); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + +constexpr int intDestArray() { + new ((void*)2) int[4]; // both-note {{cast that performs the conversions of a reinterpret_cast}} + return 0; +} +static_assert(intDestArray() == 0); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + `````````` </details> https://github.com/llvm/llvm-project/pull/164804 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
