summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2014-08-04 04:34:27 +0000
committerBill Wendling <isanbard@gmail.com>2014-08-04 04:34:27 +0000
commitbf3eda5d19f8180e79b3597bf826c56c037f30cf (patch)
treeaf630b718d9faaffb82a4b459c78f8150b39d188
parent2631339ebf29726c108a33f228c0908b1470412c (diff)
Merging r213609:
------------------------------------------------------------------------ r213609 | rtrieu | 2014-07-21 20:33:01 -0700 (Mon, 21 Jul 2014) | 3 lines Fix a template diffing problem were an '&' is unexpectedly printed in a template argument. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_35@214690 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ASTDiagnostic.cpp32
-rw-r--r--test/Misc/diag-template-diffing.cpp16
2 files changed, 42 insertions, 6 deletions
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 2ee26fb7a7..15e288acb9 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -991,12 +991,32 @@ class TemplateDiff {
if (!HasToValueDecl && ToExpr)
ToValueDecl = GetValueDecl(ToIter, ToExpr);
QualType ArgumentType = DefaultNTTPD->getType();
- bool FromAddressOf = FromValueDecl &&
- !ArgumentType->isReferenceType() &&
- !FromValueDecl->getType()->isArrayType();
- bool ToAddressOf = ToValueDecl &&
- !ArgumentType->isReferenceType() &&
- !ToValueDecl->getType()->isArrayType();
+ bool FromAddressOf = false;
+ if (FromValueDecl) {
+ if (FromExpr) {
+ if (UnaryOperator *UO = dyn_cast<UnaryOperator>(FromExpr)) {
+ if (UO->getOpcode() == UO_AddrOf)
+ FromAddressOf = true;
+ }
+ } else {
+ if (!ArgumentType->isReferenceType()) {
+ FromAddressOf = true;
+ }
+ }
+ }
+ bool ToAddressOf = false;
+ if (ToValueDecl) {
+ if (ToExpr) {
+ if (UnaryOperator *UO = dyn_cast<UnaryOperator>(ToExpr)) {
+ if (UO->getOpcode() == UO_AddrOf) {
+ ToAddressOf = true;
+ }
+ }
+ } else {
+ if (!ArgumentType->isReferenceType())
+ ToAddressOf = true;
+ }
+ }
Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
Tree.SetSame(FromValueDecl && ToValueDecl &&
FromValueDecl->getCanonicalDecl() ==
diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp
index c43ed263c6..41cdca4712 100644
--- a/test/Misc/diag-template-diffing.cpp
+++ b/test/Misc/diag-template-diffing.cpp
@@ -1105,6 +1105,22 @@ using F = C<21 + 21>;
}
}
+namespace AddressOf {
+template <int*>
+struct S {};
+
+template <class T>
+struct Wrapper {};
+
+template <class T>
+Wrapper<T> MakeWrapper();
+int global;
+constexpr int * ptr = nullptr;
+Wrapper<S<ptr>> W = MakeWrapper<S<&global>>();
+// Don't print an extra '&' for 'ptr'
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<ptr>>'
+}
+
// CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
// CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
// CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.