-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang][bytecode] Catch placement-new into invalid destination #164804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Member
|
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesWe failed to check for null and non-block pointers. Fixes #152952 Full diff: https://github.com/llvm/llvm-project/pull/164804.diff 4 Files Affected:
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}}
+
|
We failed to check for null and non-block pointers. Fixes llvm#152952
720b346 to
bd82225
Compare
dvbuka
pushed a commit
to dvbuka/llvm-project
that referenced
this pull request
Oct 27, 2025
…164804) We failed to check for null and non-block pointers. Fixes llvm#152952
Lukacma
pushed a commit
to Lukacma/llvm-project
that referenced
this pull request
Oct 29, 2025
…164804) We failed to check for null and non-block pointers. Fixes llvm#152952
aokblast
pushed a commit
to aokblast/llvm-project
that referenced
this pull request
Oct 30, 2025
…164804) We failed to check for null and non-block pointers. Fixes llvm#152952
shafik
reviewed
Nov 17, 2025
| // both-note {{in call to}} | ||
|
|
||
| constexpr int nullArrayDest() { | ||
| new (nullptr) int{12}; // both-note {{construction of dereferenced null pointer}} |
Collaborator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you intended to make this an array but did not.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
clang:bytecode
Issues for the clang bytecode constexpr interpreter
clang:frontend
Language frontend issues, e.g. anything involving "Sema"
clang
Clang issues not falling into any other category
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We failed to check for null and non-block pointers.
Fixes #152952