Skip to content

Commit

Permalink
[AST] Fix crash in evaluation of OpaqueExpr in Clangd
Browse files Browse the repository at this point in the history
The code mistakenly returns the value as evaluated whenever the
temporary is allocated, but not yet evaluated.

I could only reproduce in Clangd and could not come up with an example
that would crash the compiler. Clangd runs more evaluations for hover
than the language would allow.

Reviewed By: kadircet

Differential Revision: https://reviews.llvm.org/D158985
  • Loading branch information
ilya-biryukov committed Aug 28, 2023
1 parent 3610c82 commit d703dcd
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
26 changes: 26 additions & 0 deletions clang-tools-extra/clangd/unittests/HoverTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2967,6 +2967,32 @@ TEST(Hover, All) {
HI.NamespaceScope = "";
HI.Value = "0";
}},
// Should not crash.
{R"objc(
typedef struct MyRect {} MyRect;
@interface IFace
@property(nonatomic) MyRect frame;
@end
MyRect foobar() {
MyRect mr;
return mr;
}
void test() {
IFace *v;
v.frame = [[foo^bar]]();
}
)objc",
[](HoverInfo &HI) {
HI.Name = "foobar";
HI.Kind = index::SymbolKind::Function;
HI.NamespaceScope = "";
HI.Definition = "MyRect foobar()";
HI.Type = {"MyRect ()", "MyRect ()"};
HI.ReturnType = {"MyRect", "MyRect"};
HI.Parameters.emplace();
}},
{R"cpp(
void foo(int * __attribute__(([[non^null]], noescape)) );
)cpp",
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7653,7 +7653,8 @@ class ExprEvaluatorBase
}

bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
if (APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
if (APValue *Value = Info.CurrentCall->getCurrentTemporary(E);
Value && !Value->isAbsent())
return DerivedSuccess(*Value, E);

const Expr *Source = E->getSourceExpr();
Expand Down

0 comments on commit d703dcd

Please sign in to comment.