diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3879,8 +3879,11 @@ // C++0x [temp.deduct.call]p3: // If P is a cv-qualified type, the top level cv-qualifiers of P's type // are ignored for type deduction. - if (ParamType.hasQualifiers()) + // Ignore top level nullability qualifiers too. + if (ParamType.hasQualifiers()) { ParamType = ParamType.getUnqualifiedType(); + (void)AttributedType::stripOuterNullability(ParamType); + } // [...] If P is a reference type, the type referred to by P is // used for type deduction. @@ -3927,7 +3930,9 @@ else { // - If A is a cv-qualified type, the top level cv-qualifiers of A's // type are ignored for type deduction. + // Ignore top level nullability qualifiers too. ArgType = ArgType.getUnqualifiedType(); + (void)AttributedType::stripOuterNullability(ArgType); } } diff --git a/clang/test/Sema/nullability.c b/clang/test/Sema/nullability.c --- a/clang/test/Sema/nullability.c +++ b/clang/test/Sema/nullability.c @@ -125,9 +125,11 @@ int *a = ptr; // okay _Nonnull int *b = ptr; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}} b = ptr; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}} - __auto_type _Nonnull c = ptr; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nullable _Nonnull'}} + __auto_type _Nonnull c = ptr; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}} accepts_nonnull_1(ptr); // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}} + __auto_type d = ptr; // _Nullable on ptr is ignored when d's type is deduced. + b = d; // OK. } // Check nullability of conditional expressions. diff --git a/clang/test/SemaCXX/nullability.cpp b/clang/test/SemaCXX/nullability.cpp --- a/clang/test/SemaCXX/nullability.cpp +++ b/clang/test/SemaCXX/nullability.cpp @@ -137,6 +137,21 @@ Template tip; } +namespace test_auto { + +template +void foo(T t) { + int * _Nonnull x = t; // OK. +} + +void test(int * _Nullable ptr) { + auto b = ptr; // _Nullable on ptr is ignored when b's type is deduced. + int * _Nonnull c = b; // OK. + foo(ptr); // _Nullable on ptr is ignored when T's type is deduced. +} + +} + namespace GH60344 { class a; template using c = b _Nullable; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'GH60344::a'}}