171 lines · cpp
1// RUN: %clang_cc1 -Wread-only-types %s -verify -fsyntax-only2// RUN: %clang_cc1 -std=c++2a -Wread-only-types %s -verify -fsyntax-only3// RUN: %clang_cc1 -std=c++17 -Wread-only-types %s -verify -fsyntax-only4 5struct __attribute__((enforce_read_only_placement)) A { // #A_DECL6};7 8A a1; // expected-warning {{object of type 'A' cannot be placed in read-only memory}}9 // expected-note@#A_DECL {{type was declared read-only here}}10const A a2[10]; // no-warning11A a3[20]; // expected-warning {{object of type 'A' cannot be placed in read-only memory}}12 // expected-note@#A_DECL {{type was declared read-only here}}13 14 15 16struct B;17struct __attribute__((enforce_read_only_placement)) B { //#B_DECL18};19 20B b1; // expected-warning {{object of type 'B' cannot be placed in read-only memory}}21 // expected-note@#B_DECL {{type was declared read-only here}}22const B b2; // no-warning23const B b3[4]; // no-warning24B b4[5]; // expected-warning {{object of type 'B' cannot be placed in read-only memory}}25 // expected-note@#B_DECL {{type was declared read-only here}}26B b5[5][5]; // expected-warning {{object of type 'B' cannot be placed in read-only memory}}27 // expected-note@#B_DECL {{type was declared read-only here}}28B b10[5][5][5]; // expected-warning {{object of type 'B' cannot be placed in read-only memory}}29 // expected-note@#B_DECL {{type was declared read-only here}}30 31void method1() {32 static const B b6;33 static B b7;// expected-warning {{object of type 'B' cannot be placed in read-only memory}}34 // expected-note@#B_DECL {{type was declared read-only here}}35 B b8; // no-warning36 const B b9; // no-warning37}38 39struct C;40struct __attribute__((enforce_read_only_placement)) C; // expected-note {{type was declared read-only here}}41struct C { // no-note. The note should be attached to the definition/declaration bearing the attribute42};43 44C c1; // expected-warning {{object of type 'C' cannot be placed in read-only memory}}45 46// Cases to be handled by the follow-up patches.47 48// Attaching and checking the attribute in reverse, where the attribute is attached after the49// type definition50struct D;51struct D { //expected-note{{previous definition is here}}52};53struct __attribute__((enforce_read_only_placement)) D; // #354 // expected-warning@#3{{attribute declaration must precede definition}}55 56D d1; // We do not emit a warning here, as there is another warning for declaring57 // a type after the definition58 59 60// Cases where the attribute must be explicitly attached to another type61// Case 1: Inheriting from a type that has the attribute62struct E : C { // FIXME: warn the user declarations of type `E`, that extends `C`, won't be63 // checked for read only placement because `E` is not marked as `C` is.64};65 66// Case 2: Declaring a field of the type that has the attribute67struct F {68 C c1; // FIXME: warn the user type `F` that wraps type `C` won't be checked for69 // read only placement70};71 72struct BaseWithoutAttribute {73 int a;74};75 76struct __attribute__((enforce_read_only_placement)) J : BaseWithoutAttribute { // no-warning77};78 79struct __attribute__((enforce_read_only_placement)) BaseWithAttribute {80 int i;81};82 83struct __attribute__((enforce_read_only_placement)) Derived : BaseWithAttribute { // no-warning84 int j;85};86 87struct __attribute__((enforce_read_only_placement)) WrapperToAttributeInstance { // no-warning88 BaseWithAttribute b;89};90 91struct __attribute__((enforce_read_only_placement)) WrapperToNoAttributeInstance { // no-warning92 BaseWithoutAttribute b;93};94 95// Cases where the const qualification doesn't ensure read-only memory placement96// of an instance.97 98// Case 1: The type defines/inherits mutable data members99struct __attribute__((enforce_read_only_placement)) G {100 mutable int x; // FIXME: warn the user type `G` won't be placed in the read only program memory101};102 103struct __attribute__((enforce_read_only_placement)) H : public G { // FIXME: Warn the user type `H`104 // won't be placed in the read only program memory105};106 107struct __attribute__((enforce_read_only_placement)) K { // FIXME : Warn the user type `K` w on't be108 // placed in the read only program memory109 G g;110};111 112 113// Case 2: The type has a constructor that makes its fields modifiable114struct __attribute__((enforce_read_only_placement)) L {115 int b;116 L(int val) { // FIXME: warn the user type `L` won't be placed in the read only program memory117 b = val;118 }119};120 121struct __attribute__((enforce_read_only_placement)) ConstInClassInitializers { // no-warning122 int b = 12;123 124 ConstInClassInitializers() = default;125};126 127int foo();128struct __attribute__((enforce_read_only_placement)) NonConstInClassInitializers {129 int b = foo(); // FIXME: warn the user type `NonConstInClassInitializers` won't be placed130 // in the read only program memory131 132 NonConstInClassInitializers() = default;133};134 135#if (__cplusplus >= 202002L)136struct __attribute__((enforce_read_only_placement)) ConstevalCtor {137 int b;138 139 consteval ConstevalCtor(int B) : b(B) {} // no-warning140};141#endif142 143#if (__cplusplus >= 201103L)144struct __attribute__((enforce_read_only_placement)) ConstExprCtor { // no-warning145 int b;146 147 constexpr ConstExprCtor(int B) : b(B) {}148};149 150constexpr ConstExprCtor cec1(10); // no-warning151 152#endif153 154// Cases where an object is allocated on the heap or on the stack155C *c2 = new C; // FIXME: warn the user this instance of 'C' won't be placed in the read only program memory156 157void func1(C c); // FIXME: warn the user the instance of 'C' won't be placed in the read only program memory158 159void func2(const C c); // FIXME: warn the user the instance of 'C' won't be placed in the read160 // only program memory161 162C func3(); // FIXME: warn the user the instance of 'C' won't be placed in the read only program memory163 164void func4() {165 C c; // FIXME: warn the user the instance of 'C' won't be placed in the read only program memory166}167 168#if (__cplusplus >= 202002L)169consteval void func4(C c); // no-warning170#endif171