зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1425984 - Backport LLVM revision 318309 to fix clang-cl bustage with VS2017 15.5. r=dmajor
This commit is contained in:
Родитель
cdd4f12a89
Коммит
5426c586b0
|
@ -12,6 +12,7 @@
|
|||
"cc": "cl.exe",
|
||||
"cxx": "cl.exe",
|
||||
"patches": [
|
||||
"r318309.patch",
|
||||
"msvc-host-x64.patch",
|
||||
"loosen-msvc-detection.patch"
|
||||
]
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"cxx": "cl.exe",
|
||||
"ml": "ml64.exe",
|
||||
"patches": [
|
||||
"r318309.patch",
|
||||
"loosen-msvc-detection.patch",
|
||||
"hide-gcda-profiling-symbols.patch",
|
||||
"fflush-before-unlocking.patch"
|
||||
|
|
|
@ -0,0 +1,279 @@
|
|||
From a53ee5453ba652fc640467847415dd44c24fed02 Mon Sep 17 00:00:00 2001
|
||||
From: Hans Wennborg <hans@hanshq.net>
|
||||
Date: Wed, 15 Nov 2017 17:11:53 +0000
|
||||
Subject: [PATCH] BuiltinOperatorOverloadBuilder: Don't consider types that are
|
||||
unavailable on the target (PR35174)
|
||||
|
||||
In the PR, Clang ended up in a situation where it tried to mangle the
|
||||
__float128 type, which isn't supported when targetingt MSVC, because
|
||||
Clang instantiated a variable template with that type when searching for
|
||||
a conversion to use in an arithmetic expression.
|
||||
|
||||
Differential revision: https://reviews.llvm.org/D39579
|
||||
|
||||
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318309 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||
|
||||
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
|
||||
index f4b8b4e34a8..fa6279800dc 100644
|
||||
--- a/clang/lib/Sema/SemaOverload.cpp
|
||||
+++ b/clang/lib/Sema/SemaOverload.cpp
|
||||
@@ -7615,53 +7615,62 @@ class BuiltinOperatorOverloadBuilder {
|
||||
SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes;
|
||||
OverloadCandidateSet &CandidateSet;
|
||||
|
||||
- // Define some constants used to index and iterate over the arithemetic types
|
||||
- // provided via the getArithmeticType() method below.
|
||||
- // The "promoted arithmetic types" are the arithmetic
|
||||
+ static constexpr int ArithmeticTypesCap = 24;
|
||||
+ SmallVector<CanQualType, ArithmeticTypesCap> ArithmeticTypes;
|
||||
+
|
||||
+ // Define some indices used to iterate over the arithemetic types in
|
||||
+ // ArithmeticTypes. The "promoted arithmetic types" are the arithmetic
|
||||
// types are that preserved by promotion (C++ [over.built]p2).
|
||||
- static const unsigned FirstIntegralType = 4;
|
||||
- static const unsigned LastIntegralType = 21;
|
||||
- static const unsigned FirstPromotedIntegralType = 4,
|
||||
- LastPromotedIntegralType = 12;
|
||||
- static const unsigned FirstPromotedArithmeticType = 0,
|
||||
- LastPromotedArithmeticType = 12;
|
||||
- static const unsigned NumArithmeticTypes = 21;
|
||||
-
|
||||
- /// \brief Get the canonical type for a given arithmetic type index.
|
||||
- CanQualType getArithmeticType(unsigned index) {
|
||||
- assert(index < NumArithmeticTypes);
|
||||
- static CanQualType ASTContext::* const
|
||||
- ArithmeticTypes[NumArithmeticTypes] = {
|
||||
- // Start of promoted types.
|
||||
- &ASTContext::FloatTy,
|
||||
- &ASTContext::DoubleTy,
|
||||
- &ASTContext::LongDoubleTy,
|
||||
- &ASTContext::Float128Ty,
|
||||
-
|
||||
- // Start of integral types.
|
||||
- &ASTContext::IntTy,
|
||||
- &ASTContext::LongTy,
|
||||
- &ASTContext::LongLongTy,
|
||||
- &ASTContext::Int128Ty,
|
||||
- &ASTContext::UnsignedIntTy,
|
||||
- &ASTContext::UnsignedLongTy,
|
||||
- &ASTContext::UnsignedLongLongTy,
|
||||
- &ASTContext::UnsignedInt128Ty,
|
||||
- // End of promoted types.
|
||||
-
|
||||
- &ASTContext::BoolTy,
|
||||
- &ASTContext::CharTy,
|
||||
- &ASTContext::WCharTy,
|
||||
- &ASTContext::Char16Ty,
|
||||
- &ASTContext::Char32Ty,
|
||||
- &ASTContext::SignedCharTy,
|
||||
- &ASTContext::ShortTy,
|
||||
- &ASTContext::UnsignedCharTy,
|
||||
- &ASTContext::UnsignedShortTy,
|
||||
- // End of integral types.
|
||||
- // FIXME: What about complex? What about half?
|
||||
- };
|
||||
- return S.Context.*ArithmeticTypes[index];
|
||||
+ unsigned FirstIntegralType,
|
||||
+ LastIntegralType;
|
||||
+ unsigned FirstPromotedIntegralType,
|
||||
+ LastPromotedIntegralType;
|
||||
+ unsigned FirstPromotedArithmeticType,
|
||||
+ LastPromotedArithmeticType;
|
||||
+ unsigned NumArithmeticTypes;
|
||||
+
|
||||
+ void InitArithmeticTypes() {
|
||||
+ // Start of promoted types.
|
||||
+ FirstPromotedArithmeticType = 0;
|
||||
+ ArithmeticTypes.push_back(S.Context.FloatTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.DoubleTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.LongDoubleTy);
|
||||
+ if (S.Context.getTargetInfo().hasFloat128Type())
|
||||
+ ArithmeticTypes.push_back(S.Context.Float128Ty);
|
||||
+
|
||||
+ // Start of integral types.
|
||||
+ FirstIntegralType = ArithmeticTypes.size();
|
||||
+ FirstPromotedIntegralType = ArithmeticTypes.size();
|
||||
+ ArithmeticTypes.push_back(S.Context.IntTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.LongTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.LongLongTy);
|
||||
+ if (S.Context.getTargetInfo().hasInt128Type())
|
||||
+ ArithmeticTypes.push_back(S.Context.Int128Ty);
|
||||
+ ArithmeticTypes.push_back(S.Context.UnsignedIntTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.UnsignedLongTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.UnsignedLongLongTy);
|
||||
+ if (S.Context.getTargetInfo().hasInt128Type())
|
||||
+ ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
|
||||
+ LastPromotedIntegralType = ArithmeticTypes.size();
|
||||
+ LastPromotedArithmeticType = ArithmeticTypes.size();
|
||||
+ // End of promoted types.
|
||||
+
|
||||
+ ArithmeticTypes.push_back(S.Context.BoolTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.CharTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.WCharTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.Char16Ty);
|
||||
+ ArithmeticTypes.push_back(S.Context.Char32Ty);
|
||||
+ ArithmeticTypes.push_back(S.Context.SignedCharTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.ShortTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.UnsignedCharTy);
|
||||
+ ArithmeticTypes.push_back(S.Context.UnsignedShortTy);
|
||||
+ LastIntegralType = ArithmeticTypes.size();
|
||||
+ NumArithmeticTypes = ArithmeticTypes.size();
|
||||
+ // End of integral types.
|
||||
+ // FIXME: What about complex? What about half?
|
||||
+
|
||||
+ assert(ArithmeticTypes.size() <= ArithmeticTypesCap &&
|
||||
+ "Enough inline storage for all arithmetic types.");
|
||||
}
|
||||
|
||||
/// \brief Helper method to factor out the common pattern of adding overloads
|
||||
@@ -7720,18 +7729,8 @@ class BuiltinOperatorOverloadBuilder {
|
||||
HasArithmeticOrEnumeralCandidateType),
|
||||
CandidateTypes(CandidateTypes),
|
||||
CandidateSet(CandidateSet) {
|
||||
- // Validate some of our static helper constants in debug builds.
|
||||
- assert(getArithmeticType(FirstPromotedIntegralType) == S.Context.IntTy &&
|
||||
- "Invalid first promoted integral type");
|
||||
- assert(getArithmeticType(LastPromotedIntegralType - 1)
|
||||
- == S.Context.UnsignedInt128Ty &&
|
||||
- "Invalid last promoted integral type");
|
||||
- assert(getArithmeticType(FirstPromotedArithmeticType)
|
||||
- == S.Context.FloatTy &&
|
||||
- "Invalid first promoted arithmetic type");
|
||||
- assert(getArithmeticType(LastPromotedArithmeticType - 1)
|
||||
- == S.Context.UnsignedInt128Ty &&
|
||||
- "Invalid last promoted arithmetic type");
|
||||
+
|
||||
+ InitArithmeticTypes();
|
||||
}
|
||||
|
||||
// C++ [over.built]p3:
|
||||
@@ -7758,7 +7757,7 @@ class BuiltinOperatorOverloadBuilder {
|
||||
for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1);
|
||||
Arith < NumArithmeticTypes; ++Arith) {
|
||||
addPlusPlusMinusMinusStyleOverloads(
|
||||
- getArithmeticType(Arith),
|
||||
+ ArithmeticTypes[Arith],
|
||||
VisibleTypeConversionsQuals.hasVolatile(),
|
||||
VisibleTypeConversionsQuals.hasRestrict());
|
||||
}
|
||||
@@ -7831,7 +7830,7 @@ class BuiltinOperatorOverloadBuilder {
|
||||
|
||||
for (unsigned Arith = FirstPromotedArithmeticType;
|
||||
Arith < LastPromotedArithmeticType; ++Arith) {
|
||||
- QualType ArithTy = getArithmeticType(Arith);
|
||||
+ QualType ArithTy = ArithmeticTypes[Arith];
|
||||
S.AddBuiltinCandidate(&ArithTy, Args, CandidateSet);
|
||||
}
|
||||
|
||||
@@ -7871,7 +7870,7 @@ class BuiltinOperatorOverloadBuilder {
|
||||
|
||||
for (unsigned Int = FirstPromotedIntegralType;
|
||||
Int < LastPromotedIntegralType; ++Int) {
|
||||
- QualType IntTy = getArithmeticType(Int);
|
||||
+ QualType IntTy = ArithmeticTypes[Int];
|
||||
S.AddBuiltinCandidate(&IntTy, Args, CandidateSet);
|
||||
}
|
||||
|
||||
@@ -8099,8 +8098,8 @@ class BuiltinOperatorOverloadBuilder {
|
||||
Left < LastPromotedArithmeticType; ++Left) {
|
||||
for (unsigned Right = FirstPromotedArithmeticType;
|
||||
Right < LastPromotedArithmeticType; ++Right) {
|
||||
- QualType LandR[2] = { getArithmeticType(Left),
|
||||
- getArithmeticType(Right) };
|
||||
+ QualType LandR[2] = { ArithmeticTypes[Left],
|
||||
+ ArithmeticTypes[Right] };
|
||||
S.AddBuiltinCandidate(LandR, Args, CandidateSet);
|
||||
}
|
||||
}
|
||||
@@ -8143,8 +8142,8 @@ class BuiltinOperatorOverloadBuilder {
|
||||
Left < LastPromotedIntegralType; ++Left) {
|
||||
for (unsigned Right = FirstPromotedIntegralType;
|
||||
Right < LastPromotedIntegralType; ++Right) {
|
||||
- QualType LandR[2] = { getArithmeticType(Left),
|
||||
- getArithmeticType(Right) };
|
||||
+ QualType LandR[2] = { ArithmeticTypes[Left],
|
||||
+ ArithmeticTypes[Right] };
|
||||
S.AddBuiltinCandidate(LandR, Args, CandidateSet);
|
||||
}
|
||||
}
|
||||
@@ -8324,18 +8323,18 @@ class BuiltinOperatorOverloadBuilder {
|
||||
for (unsigned Right = FirstPromotedArithmeticType;
|
||||
Right < LastPromotedArithmeticType; ++Right) {
|
||||
QualType ParamTypes[2];
|
||||
- ParamTypes[1] = getArithmeticType(Right);
|
||||
+ ParamTypes[1] = ArithmeticTypes[Right];
|
||||
|
||||
// Add this built-in operator as a candidate (VQ is empty).
|
||||
ParamTypes[0] =
|
||||
- S.Context.getLValueReferenceType(getArithmeticType(Left));
|
||||
+ S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
|
||||
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
|
||||
/*IsAssigmentOperator=*/isEqualOp);
|
||||
|
||||
// Add this built-in operator as a candidate (VQ is 'volatile').
|
||||
if (VisibleTypeConversionsQuals.hasVolatile()) {
|
||||
ParamTypes[0] =
|
||||
- S.Context.getVolatileType(getArithmeticType(Left));
|
||||
+ S.Context.getVolatileType(ArithmeticTypes[Left]);
|
||||
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
|
||||
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
|
||||
/*IsAssigmentOperator=*/isEqualOp);
|
||||
@@ -8390,15 +8389,15 @@ class BuiltinOperatorOverloadBuilder {
|
||||
for (unsigned Right = FirstPromotedIntegralType;
|
||||
Right < LastPromotedIntegralType; ++Right) {
|
||||
QualType ParamTypes[2];
|
||||
- ParamTypes[1] = getArithmeticType(Right);
|
||||
+ ParamTypes[1] = ArithmeticTypes[Right];
|
||||
|
||||
// Add this built-in operator as a candidate (VQ is empty).
|
||||
ParamTypes[0] =
|
||||
- S.Context.getLValueReferenceType(getArithmeticType(Left));
|
||||
+ S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
|
||||
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);
|
||||
if (VisibleTypeConversionsQuals.hasVolatile()) {
|
||||
// Add this built-in operator as a candidate (VQ is 'volatile').
|
||||
- ParamTypes[0] = getArithmeticType(Left);
|
||||
+ ParamTypes[0] = ArithmeticTypes[Left];
|
||||
ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]);
|
||||
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
|
||||
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);
|
||||
diff --git a/test/SemaCXX/microsoft-vs-float128.cpp b/test/SemaCXX/microsoft-vs-float128.cpp
|
||||
new file mode 100644
|
||||
index 00000000000..d271e470032
|
||||
--- /dev/null
|
||||
+++ b/test/SemaCXX/microsoft-vs-float128.cpp
|
||||
@@ -0,0 +1,34 @@
|
||||
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s
|
||||
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 -DMS %s
|
||||
+
|
||||
+template <bool> struct enable_if {};
|
||||
+template<> struct enable_if<true> { typedef void type; };
|
||||
+
|
||||
+template <typename, typename> struct is_same { static constexpr bool value = false; };
|
||||
+template <typename T> struct is_same<T, T> { static constexpr bool value = true; };
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+struct S {
|
||||
+ // The only numeric types S can be converted to is __int128 and __float128.
|
||||
+ template <typename T, typename = typename enable_if<
|
||||
+ !((__is_integral(T) && sizeof(T) != 16) ||
|
||||
+ is_same<T, float>::value ||
|
||||
+ is_same<T, double>::value ||
|
||||
+ is_same<T, long double>::value)>::type>
|
||||
+ operator T() { return T(); }
|
||||
+};
|
||||
+
|
||||
+void f() {
|
||||
+#ifdef MS
|
||||
+ // When targeting Win32, __float128 and __int128 do not exist, so the S
|
||||
+ // object cannot be converted to anything usable in the expression.
|
||||
+ // expected-error@+2{{invalid operands to binary expression ('S' and 'double')}}
|
||||
+#endif
|
||||
+ double d = S() + 1.0;
|
||||
+#ifndef MS
|
||||
+ // expected-error@-2{{use of overloaded operator '+' is ambiguous}}
|
||||
+ // expected-note@-3 36{{built-in candidate operator+}}
|
||||
+#endif
|
||||
+}
|
Загрузка…
Ссылка в новой задаче