File tree Expand file tree Collapse file tree 2 files changed +37
-0
lines changed Expand file tree Collapse file tree 2 files changed +37
-0
lines changed Original file line number Diff line number Diff line change @@ -181,6 +181,17 @@ template <PrimType Name, class T = typename PrimConv<Name>::T>
181
181
bool Ret (InterpState &S, CodePtr &PC, APValue &Result) {
182
182
const T &Ret = S.Stk .pop <T>();
183
183
184
+ // Make sure returned pointers are live. We might be trying to return a
185
+ // pointer or reference to a local variable.
186
+ // Just return false, since a diagnostic has already been emitted in Sema.
187
+ if constexpr (std::is_same_v<T, Pointer>) {
188
+ // FIXME: We could be calling isLive() here, but the emitted diagnostics
189
+ // seem a little weird, at least if the returned expression is of
190
+ // pointer type.
191
+ if (!Ret.isLive ())
192
+ return false ;
193
+ }
194
+
184
195
assert (S.Current ->getFrameOffset () == S.Stk .size () && " Invalid frame" );
185
196
if (!S.checkingPotentialConstantExpression () || S.Current ->Caller )
186
197
S.Current ->popArgs ();
Original file line number Diff line number Diff line change @@ -265,3 +265,29 @@ namespace CallWithArgs {
265
265
g (0 );
266
266
}
267
267
}
268
+
269
+ namespace ReturnLocalPtr {
270
+ constexpr int *p () {
271
+ int a = 12 ;
272
+ return &a; // ref-warning {{address of stack memory}} \
273
+ // expected-warning {{address of stack memory}}
274
+ }
275
+
276
+ // / GCC rejects the expression below, just like the new interpreter. The current interpreter
277
+ // / however accepts it and only warns about the function above returning an address to stack
278
+ // / memory. If we change the condition to 'p() != nullptr', it even succeeds.
279
+ static_assert (p() == nullptr , " " ); // ref-error {{static assertion failed}} \
280
+ // expected-error {{not an integral constant expression}}
281
+
282
+ // / FIXME: The current interpreter emits diagnostics in the reference case below, but the
283
+ // / new one does not.
284
+ constexpr const int &p2 () {
285
+ int a = 12 ; // ref-note {{declared here}}
286
+ return a; // ref-warning {{reference to stack memory associated with local variable}} \
287
+ // expected-warning {{reference to stack memory associated with local variable}}
288
+ }
289
+
290
+ static_assert (p2() == 12 , " " ); // ref-error {{not an integral constant expression}} \
291
+ // ref-note {{read of variable whose lifetime has ended}} \
292
+ // expected-error {{not an integral constant expression}}
293
+ }
You can’t perform that action at this time.
0 commit comments