@@ -1070,9 +1070,30 @@ namespace Virtual {
1070
1070
public:
1071
1071
int a = f();
1072
1072
1073
- virtual constexpr int f () { return 10 ; }
1073
+ virtual constexpr int f () const { return 10 ; }
1074
1074
};
1075
1075
1076
+ K k;
1077
+ static_assert (k.f() == 10 ); // both-error {{not an integral constant expression}} \
1078
+ // both-note {{virtual function called on object 'k' whose dynamic type is not constant}}
1079
+
1080
+ void f () {
1081
+ constexpr K k;
1082
+ static_assert (k.f () == 10 );
1083
+ }
1084
+
1085
+ void f2 () {
1086
+ K k;
1087
+ static_assert (k.f () == 10 ); // both-error {{not an integral constant expression}} \
1088
+ // both-note {{virtual function called on object 'k' whose dynamic type is not constant}}
1089
+ }
1090
+
1091
+ static_assert (K().f() == 10 );
1092
+
1093
+ void f3 () {
1094
+ static_assert (K ().f () == 10 );
1095
+ }
1096
+
1076
1097
class L : public K {
1077
1098
public:
1078
1099
int b = f();
@@ -1083,6 +1104,42 @@ namespace Virtual {
1083
1104
static_assert (l.a == 10 );
1084
1105
static_assert (l.b == 10 );
1085
1106
static_assert (l.c == 10 );
1107
+ static_assert (l.f() == 10 );
1108
+
1109
+ struct M {
1110
+ K& mk = k;
1111
+ };
1112
+ static_assert (M{}.mk.f() == 10 ); // both-error {{not an integral constant expression}} \
1113
+ // both-note {{virtual function called on object 'k' whose dynamic type is not constant}}
1114
+
1115
+ struct N {
1116
+ K* mk = &k;
1117
+ };
1118
+ static_assert (N{}.mk->f () == 10); // both-error {{not an integral constant expression}} \
1119
+ // both-note {{virtual function called on object 'k' whose dynamic type is not constant}}
1120
+
1121
+ extern K o;
1122
+ static_assert (o.f() == 10); // both-error {{not an integral constant expression}} \
1123
+ // both-note {{virtual function called on object 'o' whose dynamic type is not constant}}
1124
+ static K p;
1125
+ static_assert (p.f() == 10); // both-error {{not an integral constant expression}} \
1126
+ // both-note {{virtual function called on object 'p' whose dynamic type is not constant}}
1127
+
1128
+ void f4 () {
1129
+ static K p;
1130
+ static_assert (p.f () == 10 ); // both-error {{not an integral constant expression}} \
1131
+ // both-note {{virtual function called on object 'p' whose dynamic type is not constant}}
1132
+ }
1133
+
1134
+ const K q;
1135
+ static_assert (q.f() == 10); // both-error {{not an integral constant expression}} \
1136
+ // both-note {{virtual function called on object 'q' whose dynamic type is not constant}}
1137
+
1138
+ void f5 () {
1139
+ const K q;
1140
+ static_assert (q.f () == 10 ); // both-error {{not an integral constant expression}} \
1141
+ // both-note {{virtual function called on object 'q' whose dynamic type is not constant}}
1142
+ }
1086
1143
}
1087
1144
1088
1145
namespace DiscardedTrivialCXXConstructExpr {
@@ -1100,3 +1157,29 @@ namespace DiscardedTrivialCXXConstructExpr {
1100
1157
constexpr int y = foo(12 ); // both-error {{must be initialized by a constant expression}} \
1101
1158
// both-note {{in call to}}
1102
1159
}
1160
+
1161
+ namespace VirtualFunctionCallThroughArrayElem {
1162
+ struct X {
1163
+ constexpr virtual int foo () const {
1164
+ return 3 ;
1165
+ }
1166
+ };
1167
+ constexpr X xs[5 ];
1168
+ static_assert (xs[3 ].foo() == 3 );
1169
+
1170
+ constexpr X xs2[1 ][2 ];
1171
+ static_assert (xs2[0 ].foo() == 3 ); // both-error {{is not a structure or union}}
1172
+ static_assert (xs2[0 ][0 ].foo() == 3 );
1173
+
1174
+ struct Y : public X {
1175
+ constexpr int foo () const override {
1176
+ return 1 ;
1177
+ }
1178
+ };
1179
+ constexpr Y ys[20 ];
1180
+ static_assert (ys[12 ].foo() == static_cast <const X&>(ys[12 ]).foo());
1181
+
1182
+ X a[3 ][4 ];
1183
+ static_assert (a[2 ][3 ].foo()); // both-error {{not an integral constant expression}} \
1184
+ // both-note {{virtual function called on object 'a[2][3]' whose dynamic type is not constant}}
1185
+ }
0 commit comments