@@ -317,6 +317,7 @@ class TestSimplifyTemplate : public TestFixture {
317317 TEST_CASE (templateTypeDeductionMultiPass); // a pending deduction survives later simplifier passes
318318 TEST_CASE (templateTypeDeductionEnum); // enum arguments deduce the enum, not its underlying type
319319 TEST_CASE (templateTypeDeductionArray); // array arguments: only the decayed dimension is a pointer
320+ TEST_CASE (templateTypeDeductionConstPointer); // "const T *": the parameter provides the pointee const
320321
321322 TEST_CASE (simplifyTemplateArgs1);
322323 TEST_CASE (simplifyTemplateArgs2);
@@ -7376,6 +7377,58 @@ class TestSimplifyTemplate : public TestFixture {
73767377 ASSERT_EQUALS (" " , errout_str ());
73777378 }
73787379
7380+ void templateTypeDeductionConstPointer ()
7381+ {
7382+ { // T must not include the const that the parameter already provides, otherwise
7383+ // every T local of the instantiation becomes a constant
7384+ const char code[] = " template<class T> T sum(const T* p, int n) {\n "
7385+ " T s = 0;\n "
7386+ " for (int i = 0; i < n; ++i)\n "
7387+ " s += p[i];\n "
7388+ " return s;\n "
7389+ " }\n "
7390+ " int g(const int* p, int n) { return sum(p, n); }" ;
7391+ const char exp[] = " int sum<int> ( const int * p , int n ) ; "
7392+ " int g ( const int * p , int n ) { return sum<int> ( p , n ) ; } "
7393+ " int sum<int> ( const int * p , int n ) { "
7394+ " int s ; s = 0 ; "
7395+ " for ( int i = 0 ; i < n ; ++ i ) { "
7396+ " s += p [ i ] ; "
7397+ " } "
7398+ " return s ; "
7399+ " }" ;
7400+ ASSERT_EQUALS (exp, tok (code));
7401+ ASSERT_EQUALS (" " , errout_str ());
7402+ }
7403+ { // the const at the other pointer levels is part of T
7404+ const char code[] = " template<class T> void f(const T* p) {}\n "
7405+ " template<class T> void h(T* p) {}\n "
7406+ " void g(const int* a, int* b, const int** c, int* const* d, const char* const e) {\n "
7407+ " f(a); f(b); f(c); f(d); f(e); h(a); h(b); h(d);\n "
7408+ " }" ;
7409+ const char exp[] = " void f<int> ( const int * p ) ; "
7410+ " void f<constint*> ( const int * const * p ) ; "
7411+ " void f<int*> ( int * const * p ) ; "
7412+ " void f<char> ( const char * p ) ; "
7413+ " void h<constint> ( const int * p ) ; "
7414+ " void h<int> ( int * p ) ; "
7415+ " void h<int*const> ( int * const * p ) ; "
7416+ " void g ( const int * a , int * b , const int * * c , int * const * d , const char * const e ) { "
7417+ " f<int> ( a ) ; f<int> ( b ) ; f<constint*> ( c ) ; f<int*> ( d ) ; f<char> ( e ) ; "
7418+ " h<constint> ( a ) ; h<int> ( b ) ; h<int*const> ( d ) ; "
7419+ " } "
7420+ " void h<constint> ( const int * p ) { } "
7421+ " void h<int> ( int * p ) { } "
7422+ " void h<int*const> ( int * const * p ) { } "
7423+ " void f<int> ( const int * p ) { } "
7424+ " void f<constint*> ( const int * const * p ) { } "
7425+ " void f<int*> ( int * const * p ) { } "
7426+ " void f<char> ( const char * p ) { }" ;
7427+ ASSERT_EQUALS (exp, tok (code));
7428+ ASSERT_EQUALS (" " , errout_str ());
7429+ }
7430+ }
7431+
73797432 void simplifyTemplateArgs1 () {
73807433 ASSERT_EQUALS (" foo<2> = 2 ; foo<2> ;" , tok (" template<int N> foo = N; foo < ( 2 ) >;\n " ));
73817434 ASSERT_EQUALS (" foo<2> = 2 ; foo<2> ;" , tok (" template<int N> foo = N; foo < 1 + 1 >;\n " ));
0 commit comments