ahatanak created this revision. ahatanak added reviewers: doug.gregor, rjmccall. ahatanak added a project: clang. Herald added a project: All. ahatanak requested review of this revision.
Prior to https://reviews.llvm.org/D110216, the deduced types didn't inherit the nullability qualifiers of the initializer expressions. This patch restores the previous behavior. See https://developer.apple.com/forums/thread/726000#726000021 for background. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D156728 Files: clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/Sema/nullability.c clang/test/SemaCXX/nullability.cpp Index: clang/test/SemaCXX/nullability.cpp =================================================================== --- clang/test/SemaCXX/nullability.cpp +++ clang/test/SemaCXX/nullability.cpp @@ -137,6 +137,21 @@ Template<int*> tip; } +namespace test_auto { + +template <class T> +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 <typename b> using c = b _Nullable; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'GH60344::a'}} Index: clang/test/Sema/nullability.c =================================================================== --- clang/test/Sema/nullability.c +++ 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. Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ 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); } }
Index: clang/test/SemaCXX/nullability.cpp =================================================================== --- clang/test/SemaCXX/nullability.cpp +++ clang/test/SemaCXX/nullability.cpp @@ -137,6 +137,21 @@ Template<int*> tip; } +namespace test_auto { + +template <class T> +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 <typename b> using c = b _Nullable; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'GH60344::a'}} Index: clang/test/Sema/nullability.c =================================================================== --- clang/test/Sema/nullability.c +++ 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. Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ 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); } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits