[PATCH] Canonicalize UnaryTransformType types when they don't have a known underlying type

Vassil Vassilev via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 6 23:09:50 PST 2016


Hi all,
   I am attaching a fix for https://llvm.org/bugs/show_bug.cgi?id=26014
   To which type should I tie the canonical type of the unknown 
underlying type? Currently it is tied to its BaseType.

   Please review.
--Vassil
-------------- next part --------------
From 5449ae8bc2c7989c904ee67a8d5ca2fe3ee20fcf Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev at gmail.com>
Date: Mon, 4 Jan 2016 20:48:36 +0200
Subject: [PATCH] Canonicalize UnaryTransformType types when they don't have a
 known underlying type.

Fixes https://llvm.org/bugs/show_bug.cgi?id=26014
---
 lib/AST/ASTContext.cpp                       | 14 ++++++++++----
 test/Modules/Inputs/PR26014/A.h              | 13 +++++++++++++
 test/Modules/Inputs/PR26014/B.h              | 10 ++++++++++
 test/Modules/Inputs/PR26014/module.modulemap |  9 +++++++++
 test/Modules/pr26014.cpp                     |  7 +++++++
 test/SemaCXX/underlying_type.cpp             |  5 +++++
 6 files changed, 54 insertions(+), 4 deletions(-)
 create mode 100644 test/Modules/Inputs/PR26014/A.h
 create mode 100644 test/Modules/Inputs/PR26014/B.h
 create mode 100644 test/Modules/Inputs/PR26014/module.modulemap
 create mode 100644 test/Modules/pr26014.cpp

diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e4c0fdb..4e6fe3c 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3971,11 +3971,17 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType,
                                            QualType UnderlyingType,
                                            UnaryTransformType::UTTKind Kind)
     const {
+
+  QualType CanonTy = getCanonicalType(UnderlyingType);
+  // Canonicalize UnaryTransformType types when they don't have a known
+  // underlying type. We want underlying_type<T>::type instances to have the
+  // same canonical types.
+  if (UnderlyingType->isDependentType())
+    CanonTy = getCanonicalType(BaseType);
+
   UnaryTransformType *Ty =
-    new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType, 
-                                                   Kind,
-                                 UnderlyingType->isDependentType() ?
-                                 QualType() : getCanonicalType(UnderlyingType));
+    new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType,
+                                                   Kind, CanonTy);
   Types.push_back(Ty);
   return QualType(Ty, 0);
 }
diff --git a/test/Modules/Inputs/PR26014/A.h b/test/Modules/Inputs/PR26014/A.h
new file mode 100644
index 0000000..49de5ba
--- /dev/null
+++ b/test/Modules/Inputs/PR26014/A.h
@@ -0,0 +1,13 @@
+#ifndef _LIBCPP_TYPE_TRAITS
+#define _LIBCPP_TYPE_TRAITS
+
+
+template <class _Tp>
+struct underlying_type
+{
+    typedef __underlying_type(_Tp) type;
+};
+
+#endif  // _LIBCPP_TYPE_TRAITS
+
+#include "B.h"
diff --git a/test/Modules/Inputs/PR26014/B.h b/test/Modules/Inputs/PR26014/B.h
new file mode 100644
index 0000000..58d1f8f
--- /dev/null
+++ b/test/Modules/Inputs/PR26014/B.h
@@ -0,0 +1,10 @@
+#ifndef _LIBCPP_TYPE_TRAITS
+#define _LIBCPP_TYPE_TRAITS
+
+template <class _Tp>
+struct underlying_type
+{
+    typedef __underlying_type(_Tp) type;
+};
+
+#endif  // _LIBCPP_TYPE_TRAITS
diff --git a/test/Modules/Inputs/PR26014/module.modulemap b/test/Modules/Inputs/PR26014/module.modulemap
new file mode 100644
index 0000000..4937418
--- /dev/null
+++ b/test/Modules/Inputs/PR26014/module.modulemap
@@ -0,0 +1,9 @@
+module A {
+  header "A.h"
+  export *
+}
+
+module B {
+  header "B.h"
+  export *
+}
diff --git a/test/Modules/pr26014.cpp b/test/Modules/pr26014.cpp
new file mode 100644
index 0000000..f9ebd4e
--- /dev/null
+++ b/test/Modules/pr26014.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/PR26014 -verify %s
+// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/PR26014/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR26014 -verify %s
+
+#include "A.h"
+
+// expected-no-diagnostics
diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp
index 61208c7..2d0695c 100644
--- a/test/SemaCXX/underlying_type.cpp
+++ b/test/SemaCXX/underlying_type.cpp
@@ -55,3 +55,8 @@ namespace PR19966 {
     // expected-error at -2 {{constant expression}}
   };
 }
+
+template<typename T> void f(__underlying_type(T));
+template<typename T> void f(__underlying_type(T));
+enum E {};
+void PR26014() { f<E>(0); } // should not yield an ambiguity error.
-- 
2.3.8 (Apple Git-58)



More information about the cfe-commits mailing list