[clang] 7e45912 - [clang] Do not crash on arrow operator on dependent type.

Adam Czachorowski via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 25 07:52:57 PDT 2022


Author: Adam Czachorowski
Date: 2022-03-25T15:48:08+01:00
New Revision: 7e459126185f4d5115e6e2166a866aba1369d024

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

LOG: [clang] Do not crash on arrow operator on dependent type.

There seems to be more than one way to get to that state. I included to
example cases in the test, both were noticed recently.

There is room for improvement, for example by creating RecoveryExpr in
place of the bad initializer, but for now let's stop the crashes.

Differential Revision: https://reviews.llvm.org/D121824

Added: 
    

Modified: 
    clang/lib/Sema/TreeTransform.h
    clang/test/SemaCXX/arrow-operator.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index fb830ef2a118a..1ee457b0566ae 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14757,6 +14757,10 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
       return getSema().CreateBuiltinArraySubscriptExpr(
           First, Callee->getBeginLoc(), Second, OpLoc);
   } else if (Op == OO_Arrow) {
+    // It is possible that the type refers to a RecoveryExpr created earlier
+    // in the tree transformation.
+    if (First->getType()->isDependentType())
+      return ExprError();
     // -> is never a builtin operation.
     return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
   } else if (Second == nullptr || isPostIncDec) {

diff  --git a/clang/test/SemaCXX/arrow-operator.cpp b/clang/test/SemaCXX/arrow-operator.cpp
index 3e32a6ba33eb2..c6d2a99251be4 100644
--- a/clang/test/SemaCXX/arrow-operator.cpp
+++ b/clang/test/SemaCXX/arrow-operator.cpp
@@ -65,3 +65,51 @@ void test() {
 }
 
 } // namespace arrow_suggest
+
+namespace no_crash_dependent_type {
+
+template <class T>
+struct A {
+  void call();
+  A *operator->();
+};
+
+template <class T>
+void foo() {
+  // The "requires an initializer" error seems unnecessary.
+  A<int> &x = blah[7]; // expected-error {{use of undeclared identifier 'blah'}} \
+                        // expected-error {{requires an initializer}}
+  // x is dependent.
+  x->call();
+}
+
+void test() {
+  foo<int>(); // expected-note {{requested here}}
+}
+
+} // namespace no_crash_dependent_type
+
+namespace clangd_issue_1073_no_crash_dependent_type {
+
+template <typename T> struct Ptr {
+  T *operator->();
+};
+
+struct Struct {
+  int len;
+};
+
+template <int>
+struct TemplateStruct {
+  Ptr<Struct> val(); // expected-note {{declared here}}
+};
+
+template <int I>
+void templateFunc(const TemplateStruct<I> &ts) {
+  Ptr<Struct> ptr = ts.val(); // expected-error {{function is not marked const}}
+  auto foo = ptr->len;
+}
+
+template void templateFunc<0>(const TemplateStruct<0> &); // expected-note {{requested here}}
+
+} // namespace clangd_issue_1073_no_crash_dependent_type


        


More information about the cfe-commits mailing list