Skip to content

Commit ecbce0c

Browse files
tbaederrcjdb
authored andcommitted
[clang][bytecode] Fix diagnostic in final ltor cast (llvm#105292)
Don't diagnose volatile reads but diagnose a few other accesses earlier.
1 parent 608d225 commit ecbce0c

File tree

5 files changed

+36
-4
lines changed

5 files changed

+36
-4
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2556,7 +2556,7 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
25562556

25572557
if (DiscardResult)
25582558
return this->emitPopPtr(E);
2559-
return true;
2559+
return this->emitFinishInit(E);
25602560
}
25612561

25622562
if (T->isArrayType()) {

clang/lib/AST/ByteCode/EvalEmitter.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,16 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
165165
if (ConvertResultToRValue) {
166166
if (!Ptr.isZero() && !Ptr.isDereferencable())
167167
return false;
168+
169+
if (S.getLangOpts().CPlusPlus11 && Ptr.isBlockPointer() &&
170+
!CheckFinalLoad(S, OpPC, Ptr)) {
171+
return false;
172+
}
173+
168174
// Never allow reading from a non-const pointer, unless the memory
169175
// has been created in this evaluation.
170-
if (!Ptr.isZero() && Ptr.isBlockPointer() &&
171-
Ptr.block()->getEvalID() != Ctx.getEvalID() &&
172-
(!CheckLoad(S, OpPC, Ptr, AK_Read) || !Ptr.isConst()))
176+
if (!Ptr.isZero() && !Ptr.isConst() && Ptr.isBlockPointer() &&
177+
Ptr.block()->getEvalID() != Ctx.getEvalID())
173178
return false;
174179

175180
if (std::optional<APValue> V =

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,31 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
559559
return true;
560560
}
561561

562+
/// This is not used by any of the opcodes directly. It's used by
563+
/// EvalEmitter to do the final lvalue-to-rvalue conversion.
564+
bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
565+
if (!CheckLive(S, OpPC, Ptr, AK_Read))
566+
return false;
567+
if (!CheckConstant(S, OpPC, Ptr))
568+
return false;
569+
570+
if (!CheckDummy(S, OpPC, Ptr, AK_Read))
571+
return false;
572+
if (!CheckExtern(S, OpPC, Ptr))
573+
return false;
574+
if (!CheckRange(S, OpPC, Ptr, AK_Read))
575+
return false;
576+
if (!CheckActive(S, OpPC, Ptr, AK_Read))
577+
return false;
578+
if (!CheckInitialized(S, OpPC, Ptr, AK_Read))
579+
return false;
580+
if (!CheckTemporary(S, OpPC, Ptr, AK_Read))
581+
return false;
582+
if (!CheckMutable(S, OpPC, Ptr))
583+
return false;
584+
return true;
585+
}
586+
562587
bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
563588
if (!CheckLive(S, OpPC, Ptr, AK_Assign))
564589
return false;

clang/lib/AST/ByteCode/Interp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
9292
/// Checks if a value can be loaded from a block.
9393
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
9494
AccessKinds AK = AK_Read);
95+
bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
9596

9697
bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
9798
AccessKinds AK);

clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 -std=c++11 %s -verify -triple x86_64-linux-gnu
2+
// RUN: %clang_cc1 -std=c++11 %s -verify -triple x86_64-linux-gnu -fexperimental-new-constant-interpreter
23

34
namespace std {
45
typedef decltype(nullptr) nullptr_t;

0 commit comments

Comments
 (0)