[clang-tools-extra] d703dcd - [AST] Fix crash in evaluation of OpaqueExpr in Clangd

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 28 08:11:31 PDT 2023


Author: Ilya Biryukov
Date: 2023-08-28T17:10:44+02:00
New Revision: d703dcdfb08dbd591589a12e0ca0852c5fd30a72

URL: https://github.com/llvm/llvm-project/commit/d703dcdfb08dbd591589a12e0ca0852c5fd30a72
DIFF: https://github.com/llvm/llvm-project/commit/d703dcdfb08dbd591589a12e0ca0852c5fd30a72.diff

LOG: [AST] Fix crash in evaluation of OpaqueExpr in Clangd

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

Added: 
    

Modified: 
    clang-tools-extra/clangd/unittests/HoverTests.cpp
    clang/lib/AST/ExprConstant.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 9cab9a086958d6..c26bda898687cb 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -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",

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 130cf23737f104..630fb02d0531e9 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -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();


        


More information about the cfe-commits mailing list