Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3ff796f

Browse files
committed
[clang][bytecode] Fix const-in-mutable fields
For mutable and const fields, we have two bits in InlineDescriptor,which both get inherited down the hierarchy. When a field is both constand mutable, we CAN read from it if it is a mutable-in-const field, butwe _can't_ read from it if it is a const-in-mutable field. We needanother bit to distinguish the two cases.
1 parentfe19419 commit3ff796f

File tree

5 files changed

+61
-10
lines changed

5 files changed

+61
-10
lines changed

‎clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,10 @@ static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
160160
Desc->IsActive = IsActive && !IsUnionField;
161161
Desc->InUnion = InUnion;
162162
Desc->IsConst = IsConst || D->IsConst;
163-
Desc->IsFieldMutable = IsMutable || D->IsMutable;
163+
Desc->IsFieldMutable =(IsMutable || D->IsMutable);
164164
Desc->IsVolatile = IsVolatile || D->IsVolatile;
165+
// True if this field is const AND the parent is mutable.
166+
Desc->IsConstInMutable = Desc->IsConst && IsMutable;
165167

166168
if (auto Fn = D->CtorFn)
167169
Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,

‎clang/lib/AST/ByteCode/Descriptor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ struct InlineDescriptor {
101101
/// Flag indicating if the field is mutable (if in a record).
102102
LLVM_PREFERRED_TYPE(bool)
103103
unsigned IsFieldMutable :1;
104+
/// Flag indicating if this field is a const field nested in
105+
/// a mutable parent field.
106+
LLVM_PREFERRED_TYPE(bool)
107+
unsigned IsConstInMutable :1;
104108
/// Flag indicating if the field is an element of a composite array.
105109
LLVM_PREFERRED_TYPE(bool)
106110
unsigned IsArrayElement :1;

‎clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
566566

567567
boolCheckConst(InterpState &S, CodePtr OpPC,const Pointer &Ptr) {
568568
assert(Ptr.isLive() &&"Pointer is not live");
569-
if (!Ptr.isConst() || Ptr.isMutable())
569+
if (!Ptr.isConst() ||!Ptr.isConstInMutable())
570570
returntrue;
571571

572572
if (!Ptr.isBlockPointer())

‎clang/lib/AST/ByteCode/Pointer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,11 @@ class Pointer {
576576
returntrue;
577577
returnisRoot() ?getDeclDesc()->IsConst :getInlineDesc()->IsConst;
578578
}
579+
boolisConstInMutable()const {
580+
if (!isBlockPointer())
581+
returnfalse;
582+
returnisRoot() ?false :getInlineDesc()->IsConstInMutable;
583+
}
579584

580585
/// Checks if an object or a subfield is volatile.
581586
boolisVolatile()const {

‎clang/test/AST/ByteCode/mutable.cpp

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++11 -verify=expected,expected11,both,both11 %s
2-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify=expected,expected14,both %s
3-
// RUN: %clang_cc1 -std=c++11 -verify=ref,ref11,both,both11 %s
4-
// RUN: %clang_cc1 -std=c++14 -verify=ref,ref14,both %s
5-
6-
7-
8-
1+
// RUN: %clang_cc1 -std=c++11 -verify=expected,expected11,both,both11 %s -fexperimental-new-constant-interpreter
2+
// RUN: %clang_cc1 -std=c++14 -verify=expected,expected14,both %s -fexperimental-new-constant-interpreter
3+
// RUN: %clang_cc1 -std=c++11 -verify=ref,ref11,both,both11 %s
4+
// RUN: %clang_cc1 -std=c++14 -verify=ref,ref14,both %s
95

106
namespaceSimple {
117
structS {
@@ -26,3 +22,47 @@ namespace Simple {
2622
static_assert(s2.a2 ==12,"");// both11-error {{not an integral constant expression}} \
2723
// both11-note {{initializer of 's2' is not a constant expression}}
2824
}
25+
#if __cplusplus >= 201402L
26+
namespaceConstInMutable {
27+
classB {
28+
public:
29+
30+
constint f;
31+
constexprB() : f(12) {}
32+
};
33+
classA {
34+
public:
35+
mutable B b;
36+
constexprA() = default;
37+
};
38+
constexprintconstInMutable() {
39+
A a;
40+
41+
int *m = (int*)&a.b.f;
42+
*m =12;// both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}}
43+
return1;
44+
}
45+
static_assert(constInMutable() ==1,"");// both-error {{not an integral constant expression}} \
46+
// both-note {{in call to}}
47+
}
48+
49+
namespaceMutableInConst {
50+
classC {
51+
public:
52+
mutableint c;
53+
constexprC() : c(50) {}
54+
};
55+
classD {
56+
public:
57+
C c;
58+
constexprD() {}
59+
};
60+
constexprintmutableInConst() {
61+
const D d{};
62+
int *m = (int*)&d.c.c;
63+
*m =12;
64+
return1;
65+
}
66+
static_assert(mutableInConst() ==1,"");
67+
}
68+
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp