-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[clang][bytecode] Disable location tracking for implicit field inits #150190
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
Open
tbaederr
wants to merge
1
commit into
llvm:main
Choose a base branch
from
tbaederr:init-ranges
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+74
−9
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
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesFull diff: https://github.com/llvm/llvm-project/pull/150190.diff 12 Files Affected:
diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
index 3288585683c10..b20b025f17007 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
@@ -217,7 +217,9 @@ bool ByteCodeEmitter::emitOp(Opcode Op, const Tys &...Args,
// The opcode is followed by arguments. The source info is
// attached to the address after the opcode.
emit(P, Code, Op, Success);
- if (SI)
+ if (LocOverride)
+ SrcMap.emplace_back(Code.size(), *LocOverride);
+ else if (SI)
SrcMap.emplace_back(Code.size(), SI);
(..., emit(P, Code, Args, Success));
diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.h b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
index 9e9dd5e87cd7a..fafba3f68765c 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.h
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
@@ -73,6 +73,7 @@ class ByteCodeEmitter {
ParamOffset LambdaThisCapture{0, false};
/// Local descriptors.
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
+ std::optional<SourceInfo> LocOverride = std::nullopt;
private:
/// Current compilation context.
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index e760055a8d235..b2dc17d866545 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -229,6 +229,31 @@ template <class Emitter> class StmtExprScope final {
bool OldFlag;
};
+/// When generating code for e.g. implicit field initializers in constructors,
+/// we don't have anything to point to in case the initializer causes an error.
+/// In that case, we need to disable location tracking for the initializer so
+/// we later point to the call range instead.
+template <class Emitter> class LocOverrideScope final {
+public:
+ LocOverrideScope(Compiler<Emitter> *Ctx, SourceInfo NewValue,
+ bool Enabled = true)
+ : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
+
+ if (Enabled)
+ Ctx->LocOverride = NewValue;
+ }
+
+ ~LocOverrideScope() {
+ if (Enabled)
+ Ctx->LocOverride = OldFlag;
+ }
+
+private:
+ Compiler<Emitter> *Ctx;
+ std::optional<SourceInfo> OldFlag;
+ bool Enabled;
+};
+
} // namespace interp
} // namespace clang
@@ -6000,6 +6025,10 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
if (const FieldDecl *Member = Init->getMember()) {
const Record::Field *F = R->getField(Member);
+ LocOverrideScope<Emitter> LOS(this, SourceInfo{},
+ !Init->isWritten() &&
+ !Init->isInClassMemberInitializer() &&
+ !isa<CXXConstructExpr>(InitExpr));
if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
return false;
} else if (const Type *Base = Init->getBaseClass()) {
@@ -6106,6 +6135,8 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
assert(R);
if (!R->isUnion()) {
+
+ LocOverrideScope<Emitter> LOS(this, SourceInfo{});
// First, destroy all fields.
for (const Record::Field &Field : llvm::reverse(R->fields())) {
const Descriptor *D = Field.Desc;
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index 503269399c757..7933580f8128d 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -41,6 +41,7 @@ template <class Emitter> class LoopScope;
template <class Emitter> class LabelScope;
template <class Emitter> class SwitchScope;
template <class Emitter> class StmtExprScope;
+template <class Emitter> class LocOverrideScope;
template <class Emitter> class Compiler;
struct InitLink {
@@ -334,6 +335,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
friend class LabelScope<Emitter>;
friend class SwitchScope<Emitter>;
friend class StmtExprScope<Emitter>;
+ friend class LocOverrideScope<Emitter>;
/// Emits a zero initializer.
bool visitZeroInitializer(PrimType T, QualType QT, const Expr *E);
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index 81ebc5694d6f0..5ea0045cc24f2 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -53,6 +53,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
bool CheckFullyInitialized) {
this->CheckFullyInitialized = CheckFullyInitialized;
S.EvaluatingDecl = VD;
+ S.setEvalLocation(VD->getLocation());
EvalResult.setSource(VD);
if (const Expr *Init = VD->getAnyInitializer()) {
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.h b/clang/lib/AST/ByteCode/EvalEmitter.h
index 2fe7da608c739..85a0a99fbb4b0 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.h
+++ b/clang/lib/AST/ByteCode/EvalEmitter.h
@@ -95,6 +95,7 @@ class EvalEmitter : public SourceMapper {
ParamOffset LambdaThisCapture{0, false};
/// Local descriptors.
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
+ std::optional<SourceInfo> LocOverride = std::nullopt;
private:
/// Current compilation context.
diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp
index d62a4f6275b50..fd333b3c21655 100644
--- a/clang/lib/AST/ByteCode/InterpFrame.cpp
+++ b/clang/lib/AST/ByteCode/InterpFrame.cpp
@@ -202,7 +202,18 @@ SourceRange InterpFrame::getCallRange() const {
return NullRange;
return S.EvalLocation;
}
- return S.getRange(Caller->Func, RetPC - sizeof(uintptr_t));
+
+ // Move up to the frame that has a valid location for the caller.
+ CodePtr Ret = RetPC;
+ for (const InterpFrame *C = this; C; C = C->Caller) {
+ if (!C->RetPC)
+ continue;
+ SourceRange CallRange =
+ S.getRange(C->Caller->Func, C->RetPC - sizeof(uintptr_t));
+ if (CallRange.isValid())
+ return CallRange;
+ }
+ return S.EvalLocation;
}
const FunctionDecl *InterpFrame::getCallee() const {
diff --git a/clang/lib/AST/ByteCode/State.cpp b/clang/lib/AST/ByteCode/State.cpp
index 3204d1a193a74..dc3d0da7a4a46 100644
--- a/clang/lib/AST/ByteCode/State.cpp
+++ b/clang/lib/AST/ByteCode/State.cpp
@@ -131,6 +131,7 @@ void State::addCallStack(unsigned Limit) {
const Frame *Bottom = getBottomFrame();
for (const Frame *F = Top; F != Bottom; F = F->getCaller(), ++CallIdx) {
SourceRange CallRange = F->getCallRange();
+ assert(CallRange.isValid());
// Skip this call?
if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
diff --git a/clang/test/AST/ByteCode/lifetimes.cpp b/clang/test/AST/ByteCode/lifetimes.cpp
index 5e021387348b5..5c8d56291f079 100644
--- a/clang/test/AST/ByteCode/lifetimes.cpp
+++ b/clang/test/AST/ByteCode/lifetimes.cpp
@@ -31,8 +31,7 @@ struct S {
// expected-note {{read of temporary whose lifetime has ended}}
};
constexpr int k1 = S().t; // both-error {{must be initialized by a constant expression}} \
- // ref-note {{in call to}} \
- // expected-note {{in call to}}
+ // both-note {{in call to}}
namespace MoveFnWorks {
diff --git a/clang/test/AST/ByteCode/mutable.cpp b/clang/test/AST/ByteCode/mutable.cpp
index 35c5a0389921e..f9ea71f68bc40 100644
--- a/clang/test/AST/ByteCode/mutable.cpp
+++ b/clang/test/AST/ByteCode/mutable.cpp
@@ -66,3 +66,11 @@ namespace MutableInConst {
static_assert(mutableInConst() == 1, "");
}
#endif
+
+struct D { mutable int y; }; // both-note {{declared here}}
+constexpr D d1 = { 1 };
+constexpr D d2 = d1; // both-error {{must be initialized by a constant expression}} \
+ // both-note {{read of mutable member 'y}}
+ // both-note {{in call to}}
+
+
diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp
index 3c0bdbc8c99fe..c5f1878c41734 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -546,14 +546,13 @@ namespace FaultyDtorCalledByDelete {
a = new int(13);
IF.mem = new int(100);
}
- constexpr ~Foo() { delete a; } // expected-note {{in call to}}
+ constexpr ~Foo() { delete a; }
};
constexpr int abc() {
Foo *F = new Foo();
int n = *F->a;
- delete F; // both-note {{in call to}} \
- // ref-note {{in call to}}
+ delete F; // both-note 2{{in call to}}
return n;
}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
index 270bc3cb48be9..dd0f1fc3cba8e 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s -fexperimental-new-constant-interpreter
+
// A constexpr specifier used in an object declaration declares the object as
// const.
constexpr int a = 0;
|
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.
No description provided.