@@ -56,22 +56,65 @@ static bool Jf(InterpState &S, CodePtr &PC, int32_t Offset) {
56
56
return true ;
57
57
}
58
58
59
+ static void diagnoseMissingInitializer (InterpState &S, CodePtr OpPC,
60
+ const ValueDecl *VD) {
61
+ const SourceInfo &E = S.Current ->getSource (OpPC);
62
+ S.FFDiag (E, diag::note_constexpr_var_init_unknown, 1 ) << VD;
63
+ S.Note (VD->getLocation (), diag::note_declared_at) << VD->getSourceRange ();
64
+ }
65
+
66
+ static void diagnoseNonConstVariable (InterpState &S, CodePtr OpPC,
67
+ const ValueDecl *VD);
68
+ static bool diagnoseUnknownDecl (InterpState &S, CodePtr OpPC,
69
+ const ValueDecl *D) {
70
+ const SourceInfo &E = S.Current ->getSource (OpPC);
71
+
72
+ if (isa<ParmVarDecl>(D)) {
73
+ if (S.getLangOpts ().CPlusPlus11 ) {
74
+ S.FFDiag (E, diag::note_constexpr_function_param_value_unknown) << D;
75
+ S.Note (D->getLocation (), diag::note_declared_at) << D->getSourceRange ();
76
+ } else {
77
+ S.FFDiag (E);
78
+ }
79
+ } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
80
+ if (!VD->getType ().isConstQualified ()) {
81
+ diagnoseNonConstVariable (S, OpPC, VD);
82
+ return false ;
83
+ }
84
+
85
+ // const, but no initializer.
86
+ if (!VD->getAnyInitializer ()) {
87
+ diagnoseMissingInitializer (S, OpPC, VD);
88
+ return false ;
89
+ }
90
+ }
91
+ return false ;
92
+ }
93
+
59
94
static void diagnoseNonConstVariable (InterpState &S, CodePtr OpPC,
60
95
const ValueDecl *VD) {
61
96
if (!S.getLangOpts ().CPlusPlus )
62
97
return ;
63
98
64
99
const SourceInfo &Loc = S.Current ->getSource (OpPC);
100
+ if (const auto *VarD = dyn_cast<VarDecl>(VD);
101
+ VarD && VarD->getType ().isConstQualified () &&
102
+ !VarD->getAnyInitializer ()) {
103
+ diagnoseMissingInitializer (S, OpPC, VD);
104
+ return ;
105
+ }
65
106
66
- if (VD->getType ()->isIntegralOrEnumerationType ())
107
+ if (VD->getType ()->isIntegralOrEnumerationType ()) {
67
108
S.FFDiag (Loc, diag::note_constexpr_ltor_non_const_int, 1 ) << VD;
68
- else
69
- S.FFDiag (Loc,
70
- S.getLangOpts ().CPlusPlus11
71
- ? diag::note_constexpr_ltor_non_constexpr
72
- : diag::note_constexpr_ltor_non_integral,
73
- 1 )
74
- << VD << VD->getType ();
109
+ S.Note (VD->getLocation (), diag::note_declared_at);
110
+ return ;
111
+ }
112
+
113
+ S.FFDiag (Loc,
114
+ S.getLangOpts ().CPlusPlus11 ? diag::note_constexpr_ltor_non_constexpr
115
+ : diag::note_constexpr_ltor_non_integral,
116
+ 1 )
117
+ << VD << VD->getType ();
75
118
S.Note (VD->getLocation (), diag::note_declared_at);
76
119
}
77
120
@@ -202,6 +245,9 @@ bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
202
245
if (!Ptr.isExtern ())
203
246
return true ;
204
247
248
+ if (Ptr.isInitialized ())
249
+ return true ;
250
+
205
251
if (!S.checkingPotentialConstantExpression () && S.getLangOpts ().CPlusPlus ) {
206
252
const auto *VD = Ptr.getDeclDesc ()->asValueDecl ();
207
253
diagnoseNonConstVariable (S, OpPC, VD);
@@ -369,9 +415,15 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
369
415
if (const auto *VD = Ptr.getDeclDesc ()->asVarDecl ();
370
416
VD && VD->hasGlobalStorage ()) {
371
417
const SourceInfo &Loc = S.Current ->getSource (OpPC);
372
- S.FFDiag (Loc, diag::note_constexpr_var_init_non_constant, 1 ) << VD;
373
- S.Note (VD->getLocation (), diag::note_declared_at);
418
+ if (VD->getAnyInitializer ()) {
419
+ S.FFDiag (Loc, diag::note_constexpr_var_init_non_constant, 1 ) << VD;
420
+ S.Note (VD->getLocation (), diag::note_declared_at);
421
+ } else {
422
+ diagnoseMissingInitializer (S, OpPC, VD);
423
+ }
424
+ return false ;
374
425
}
426
+
375
427
if (!S.checkingPotentialConstantExpression ()) {
376
428
S.FFDiag (S.Current ->getSource (OpPC), diag::note_constexpr_access_uninit)
377
429
<< AK << /* uninitialized=*/ true << S.Current ->getRange (OpPC);
@@ -598,33 +650,6 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
598
650
return true ;
599
651
}
600
652
601
- static bool diagnoseUnknownDecl (InterpState &S, CodePtr OpPC,
602
- const ValueDecl *D) {
603
- const SourceInfo &E = S.Current ->getSource (OpPC);
604
-
605
- if (isa<ParmVarDecl>(D)) {
606
- if (S.getLangOpts ().CPlusPlus11 ) {
607
- S.FFDiag (E, diag::note_constexpr_function_param_value_unknown) << D;
608
- S.Note (D->getLocation (), diag::note_declared_at) << D->getSourceRange ();
609
- } else {
610
- S.FFDiag (E);
611
- }
612
- } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
613
- if (!VD->getType ().isConstQualified ()) {
614
- diagnoseNonConstVariable (S, OpPC, VD);
615
- return false ;
616
- }
617
-
618
- // const, but no initializer.
619
- if (!VD->getAnyInitializer ()) {
620
- S.FFDiag (E, diag::note_constexpr_var_init_unknown, 1 ) << VD;
621
- S.Note (VD->getLocation (), diag::note_declared_at) << VD->getSourceRange ();
622
- return false ;
623
- }
624
- }
625
- return false ;
626
- }
627
-
628
653
// / We aleady know the given DeclRefExpr is invalid for some reason,
629
654
// / now figure out why and print appropriate diagnostics.
630
655
bool CheckDeclRef (InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
0 commit comments