if (EWC)
Init = EWC->getSubExpr();
- // FIXME: Why are we looking through reference initialization?
- // This causes us to incorrectly accept invalid code such as:
- // struct S { int n; };
- // int f() { goto x; S &&s = S(); x: return x.n; }
const MaterializeTemporaryExpr *M = NULL;
Init = Init->findMaterializedTemporary(M);
Init = Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
QualType QT = Init->getType();
- if (QT.isNull() || !CommaLHSs.empty())
+ if (QT.isNull())
return ScopePair(diag::note_protected_by_variable_init, 0);
const Type *T = QT.getTypePtr();
if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(Init)) {
const CXXConstructorDecl *ctor = cce->getConstructor();
- if (ctor->isTrivial() && ctor->isDefaultConstructor()) {
+ // For a variable declared without an initializer, we will have
+ // call-style initialization and the initializer will be the
+ // CXXConstructExpr with no intervening nodes.
+ if (ctor->isTrivial() && ctor->isDefaultConstructor() &&
+ VD->getInit() == Init && VD->getInitStyle() == VarDecl::CallInit) {
if (OutDiag)
InDiag = diag::note_protected_by_variable_nontriv_destructor;
else if (!Record->isPOD())
}
namespace test16 {
+ struct S { int n; };
+ int f() {
+ goto x; // expected-error {{goto into protected scope}}
+ const S &s = S(); // expected-note {{jump bypasses variable initialization}}
+x: return s.n;
+ }
+}
+
+#if __cplusplus >= 201103L
+namespace test17 {
+ struct S { int get(); private: int n; };
+ int f() {
+ goto x; // expected-error {{goto into protected scope}}
+ S s = {}; // expected-note {{jump bypasses variable initialization}}
+x: return s.get();
+ }
+}
+#endif
+
+// This test must be last, because the error prohibits further jump diagnostics.
+namespace testInvalid {
Invalid inv; // expected-error {{unknown type name}}
// Make sure this doesn't assert.
void fn()