jdoerfert created this revision.
jdoerfert added a reviewer: aaron.ballman.
Herald added a subscriber: bollu.
Herald added a project: clang.
jdoerfert requested review of this revision.

Add and pass AllowCXX not only in mergeFunctionTypes but all merge*Type
methods. Use it to determine if reference types should be stripped or
are invalid in mergeTypes. The reason for this is that
mergeFunctionTypes allows CXX functions with exception specifiers but
crashes on reference types (in the return or argument position). This is
going to be used by D88384 <https://reviews.llvm.org/D88384>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88491

Files:
  clang/include/clang/AST/ASTContext.h
  clang/lib/AST/ASTContext.cpp

Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -9179,13 +9179,15 @@
 /// QualType()
 QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
                                                bool OfBlockPointer,
-                                               bool Unqualified) {
+                                               bool Unqualified,
+                                               bool AllowCXX) {
   if (const RecordType *UT = T->getAsUnionType()) {
     RecordDecl *UD = UT->getDecl();
     if (UD->hasAttr<TransparentUnionAttr>()) {
       for (const auto *I : UD->fields()) {
         QualType ET = I->getType().getUnqualifiedType();
-        QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified);
+        QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified,
+                                 /* BlockReturnType */ false, AllowCXX);
         if (!MT.isNull())
           return MT;
       }
@@ -9199,21 +9201,23 @@
 /// parameter types
 QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs,
                                                  bool OfBlockPointer,
-                                                 bool Unqualified) {
+                                                 bool Unqualified,
+                                                 bool AllowCXX) {
   // GNU extension: two types are compatible if they appear as a function
   // argument, one of the types is a transparent union type and the other
   // type is compatible with a union member
   QualType lmerge = mergeTransparentUnionType(lhs, rhs, OfBlockPointer,
-                                              Unqualified);
+                                              Unqualified, AllowCXX);
   if (!lmerge.isNull())
     return lmerge;
 
   QualType rmerge = mergeTransparentUnionType(rhs, lhs, OfBlockPointer,
-                                              Unqualified);
+                                              Unqualified, AllowCXX);
   if (!rmerge.isNull())
     return rmerge;
 
-  return mergeTypes(lhs, rhs, OfBlockPointer, Unqualified);
+  return mergeTypes(lhs, rhs, OfBlockPointer, Unqualified,
+                    /* BlockReturnType */ false, AllowCXX);
 }
 
 QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
@@ -9234,11 +9238,11 @@
     bool UnqualifiedResult = Unqualified;
     if (!UnqualifiedResult)
       UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers());
-    retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true);
-  }
-  else
+    retType = mergeTypes(LHS, RHS, true, UnqualifiedResult,
+                         /* BlockReturnType */ true, AllowCXX);
+  } else
     retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false,
-                         Unqualified);
+                         Unqualified, /* BlockReturnType */ false, AllowCXX);
   if (retType.isNull())
     return {};
 
@@ -9323,7 +9327,7 @@
       QualType lParamType = lproto->getParamType(i).getUnqualifiedType();
       QualType rParamType = rproto->getParamType(i).getUnqualifiedType();
       QualType paramType = mergeFunctionParameterTypes(
-          lParamType, rParamType, OfBlockPointer, Unqualified);
+          lParamType, rParamType, OfBlockPointer, Unqualified, AllowCXX);
       if (paramType.isNull())
         return {};
 
@@ -9416,9 +9420,18 @@
   return {};
 }
 
-QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
-                                bool OfBlockPointer,
-                                bool Unqualified, bool BlockReturnType) {
+QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer,
+                                bool Unqualified, bool BlockReturnType,
+                                bool AllowCXX) {
+  // If AllowCXX is specifically set we strip reference types on demand.
+  assert((AllowCXX ||
+          (!LHS->getAs<ReferenceType>() && !RHS->getAs<ReferenceType>())) &&
+         "C++ references should have been stripped");
+  if (const ReferenceType *lRT = LHS->getAs<ReferenceType>())
+    LHS = lRT->getPointeeType();
+  if (const ReferenceType *rRT = RHS->getAs<ReferenceType>())
+    RHS = rRT->getPointeeType();
+
   // C++ [expr]: If an expression initially has the type "reference to T", the
   // type is adjusted to "T" prior to any further analysis, the expression
   // designates the object or function denoted by the reference, and the
@@ -9550,8 +9563,8 @@
       LHSPointee = LHSPointee.getUnqualifiedType();
       RHSPointee = RHSPointee.getUnqualifiedType();
     }
-    QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false,
-                                     Unqualified);
+    QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false, Unqualified,
+                                     BlockReturnType, AllowCXX);
     if (ResultType.isNull())
       return {};
     if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
@@ -9584,7 +9597,7 @@
           QualType(RHSPointee.getTypePtr(), RHSPteeQual.getAsOpaqueValue());
     }
     QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer,
-                                     Unqualified);
+                                     Unqualified, BlockReturnType, AllowCXX);
     if (ResultType.isNull())
       return {};
     if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
@@ -9602,8 +9615,8 @@
       LHSValue = LHSValue.getUnqualifiedType();
       RHSValue = RHSValue.getUnqualifiedType();
     }
-    QualType ResultType = mergeTypes(LHSValue, RHSValue, false,
-                                     Unqualified);
+    QualType ResultType = mergeTypes(LHSValue, RHSValue, false, Unqualified,
+                                     BlockReturnType, AllowCXX);
     if (ResultType.isNull())
       return {};
     if (getCanonicalType(LHSValue) == getCanonicalType(ResultType))
@@ -9626,7 +9639,8 @@
       RHSElem = RHSElem.getUnqualifiedType();
     }
 
-    QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified);
+    QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified,
+                                     BlockReturnType, AllowCXX);
     if (ResultType.isNull())
       return {};
 
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -2611,16 +2611,19 @@
   bool canBindObjCObjectType(QualType To, QualType From);
 
   // Functions for calculating composite types
-  QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
-                      bool Unqualified = false, bool BlockReturnType = false);
-  QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
+  QualType mergeTypes(QualType, QualType, bool OfBlockPointer = false,
+                      bool Unqualified = false, bool BlockReturnType = false,
+                      bool AllowCXX = false);
+  QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer = false,
                               bool Unqualified = false, bool AllowCXX = false);
   QualType mergeFunctionParameterTypes(QualType, QualType,
                                        bool OfBlockPointer = false,
-                                       bool Unqualified = false);
+                                       bool Unqualified = false,
+                                       bool AllowCXX = false);
   QualType mergeTransparentUnionType(QualType, QualType,
-                                     bool OfBlockPointer=false,
-                                     bool Unqualified = false);
+                                     bool OfBlockPointer = false,
+                                     bool Unqualified = false,
+                                     bool AllowCXX = false);
 
   QualType mergeObjCGCQualifiers(QualType, QualType);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to