@@ -1070,9 +1070,30 @@ namespace Virtual {
10701070 public:
10711071 int a = f();
10721072
1073- virtual constexpr int f () { return 10 ; }
1073+ virtual constexpr int f () const { return 10 ; }
10741074 };
10751075
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+
10761097 class L : public K {
10771098 public:
10781099 int b = f();
@@ -1083,6 +1104,42 @@ namespace Virtual {
10831104 static_assert (l.a == 10 );
10841105 static_assert (l.b == 10 );
10851106 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+ }
10861143}
10871144
10881145namespace DiscardedTrivialCXXConstructExpr {
@@ -1100,3 +1157,29 @@ namespace DiscardedTrivialCXXConstructExpr {
11001157 constexpr int y = foo(12 ); // both-error {{must be initialized by a constant expression}} \
11011158 // both-note {{in call to}}
11021159}
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