Skip to content

Commit 71e6e82

Browse files
mizvekovzygoloid
authored andcommitted
[clang] Fix constrained decltype(auto) deduction
Prior to this fix, constrained decltype(auto) behaves exactly the same as constrained regular auto. This fixes it so it deduces like decltype(auto). Signed-off-by: Matheus Izvekov <[email protected]> Reviewed By: rsmith Differential Revision: https://reviews.llvm.org/D98087
1 parent 2fcd872 commit 71e6e82

File tree

4 files changed

+36
-11
lines changed

4 files changed

+36
-11
lines changed

clang/lib/Sema/SemaType.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,11 +1269,10 @@ static QualType ConvertConstrainedAutoDeclSpecToType(Sema &S, DeclSpec &DS,
12691269
llvm::SmallVector<TemplateArgument, 8> TemplateArgs;
12701270
for (auto &ArgLoc : TemplateArgsInfo.arguments())
12711271
TemplateArgs.push_back(ArgLoc.getArgument());
1272-
return S.Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false,
1273-
/*IsPack=*/false,
1274-
cast<ConceptDecl>(TemplateId->Template.get()
1275-
.getAsTemplateDecl()),
1276-
TemplateArgs);
1272+
return S.Context.getAutoType(
1273+
QualType(), AutoKW, false, /*IsPack=*/false,
1274+
cast<ConceptDecl>(TemplateId->Template.get().getAsTemplateDecl()),
1275+
TemplateArgs);
12771276
}
12781277

12791278
/// Convert the specified declspec to the appropriate type

clang/test/CXX/dcl/dcl.fct/p17.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ namespace constrained {
186186
static_assert(is_same_v<decltype(f9(i, c)), void>);
187187
// expected-error@-1{{no matching}}
188188
static_assert(is_same_v<decltype(f9(i, i, ci)), void>);
189-
void f10(C decltype(auto) x);
189+
void f10(C decltype(auto) x); // expected-error{{decltype(auto)' not allowed in function prototype}}
190190
auto f11 = [] (C auto x) { };
191191
// expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}
192192
static_assert(is_same_v<decltype(f11(1)), void>);
@@ -238,7 +238,7 @@ namespace constrained {
238238
static_assert(is_same_v<decltype(f20(i, c)), void>);
239239
// expected-error@-1{{no matching}}
240240
static_assert(is_same_v<decltype(f20(c, c, cc)), void>);
241-
void f21(C2<char> decltype(auto) x);
241+
void f21(C2<char> decltype(auto) x); // expected-error{{decltype(auto)' not allowed in function prototype}}
242242
auto f22 = [] (C2<char> auto x) { };
243243
// expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}
244244
static_assert(is_same_v<decltype(f22(1)), void>);

clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// RUN: %clang_cc1 -std=c++2a -verify %s
2+
template<typename T, typename U> constexpr bool is_same_v = false;
3+
template<typename T> constexpr bool is_same_v<T, T> = true;
24

35
template<typename T, unsigned size>
46
concept LargerThan = sizeof(T) > size;
@@ -41,4 +43,28 @@ Large auto test5() -> void;
4143
auto test6() -> Large auto { return 1; }
4244

4345
X::Small auto test7() { return 'a'; }
44-
X::SmallerThan<5> auto test8() { return 10; }
46+
X::SmallerThan<5> auto test8() { return 10; }
47+
48+
namespace PR48384 {
49+
int a = 0;
50+
int &b = a;
51+
template <class T> concept True = true;
52+
53+
True auto c = a;
54+
static_assert(is_same_v<decltype(c), int>);
55+
56+
True auto d = b;
57+
static_assert(is_same_v<decltype(d), int>);
58+
59+
True decltype(auto) e = a;
60+
static_assert(is_same_v<decltype(e), int>);
61+
62+
True decltype(auto) f = b;
63+
static_assert(is_same_v<decltype(f), int&>);
64+
65+
True decltype(auto) g = (a);
66+
static_assert(is_same_v<decltype(g), int&>);
67+
68+
True decltype(auto) h = (b);
69+
static_assert(is_same_v<decltype(h), int&>);
70+
}

clang/test/Parser/cxx2a-placeholder-type-constraint.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ int foo() {
2323
{C<> decltype(auto) a = 1;}
2424
{C<int> decltype(auto) a = 1;}
2525
{const C<> decltype(auto) &a = 1;} // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}}
26-
// expected-error@-1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
26+
// expected-error@-1{{cannot form reference to 'decltype(auto)'}}
2727
{const C<int> decltype(auto) &a = 1;} // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}}
28-
// expected-error@-1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
28+
// expected-error@-1{{cannot form reference to 'decltype(auto)'}}
2929
{C a = 1;}
3030
// expected-error@-1{{expected 'auto' or 'decltype(auto)' after concept name}}
3131
{C decltype a19 = 1;}
3232
// expected-error@-1{{expected '('}}
3333
{C decltype(1) a20 = 1;}
3434
// expected-error@-1{{expected 'auto' or 'decltype(auto)' after concept name}}
35-
}
35+
}

0 commit comments

Comments
 (0)