[clang] ffcaed3 - [Matrix] Check non-dependent elt type before creating DepSizedMatrix.

Florian Hahn via cfe-commits cfe-commits at lists.llvm.org
Tue May 12 08:47:35 PDT 2020


Author: Florian Hahn
Date: 2020-05-12T16:46:37+01:00
New Revision: ffcaed32ef1cf5226cc376b6c911183db690402f

URL: https://github.com/llvm/llvm-project/commit/ffcaed32ef1cf5226cc376b6c911183db690402f
DIFF: https://github.com/llvm/llvm-project/commit/ffcaed32ef1cf5226cc376b6c911183db690402f.diff

LOG: [Matrix] Check non-dependent elt type before creating DepSizedMatrix.

We should check non-dependent element types before creating a
DependentSizedMatrixType. Otherwise we do not generate an error message
for dependent-sized matrix types with invalid non-dependent element
types, if the template is never instantiated. See the make5 struct in
the tests.

It also moves the SEMA template tests to
clang/test/SemaTemplate/matrix-type.cpp and introduces a few more test
cases.

Added: 
    clang/test/SemaTemplate/matrix-type.cpp

Modified: 
    clang/lib/Sema/SemaType.cpp
    clang/test/SemaCXX/matrix-type.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index df8ad7ad78b9..1822951266f5 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2574,11 +2574,6 @@ QualType Sema::BuildMatrixType(QualType ElementTy, Expr *NumRows, Expr *NumCols,
   assert(Context.getLangOpts().MatrixTypes &&
          "Should never build a matrix type when it is disabled");
 
-  if (NumRows->isTypeDependent() || NumCols->isTypeDependent() ||
-      NumRows->isValueDependent() || NumCols->isValueDependent())
-    return Context.getDependentSizedMatrixType(ElementTy, NumRows, NumCols,
-                                               AttrLoc);
-
   // Check element type, if it is not dependent.
   if (!ElementTy->isDependentType() &&
       !MatrixType::isValidElementType(ElementTy)) {
@@ -2586,6 +2581,11 @@ QualType Sema::BuildMatrixType(QualType ElementTy, Expr *NumRows, Expr *NumCols,
     return QualType();
   }
 
+  if (NumRows->isTypeDependent() || NumCols->isTypeDependent() ||
+      NumRows->isValueDependent() || NumCols->isValueDependent())
+    return Context.getDependentSizedMatrixType(ElementTy, NumRows, NumCols,
+                                               AttrLoc);
+
   // Both row and column values can only be 20 bit wide currently.
   llvm::APSInt ValueRows(32), ValueColumns(32);
 

diff  --git a/clang/test/SemaCXX/matrix-type.cpp b/clang/test/SemaCXX/matrix-type.cpp
index 76f288d83e6e..af31e267fdca 100644
--- a/clang/test/SemaCXX/matrix-type.cpp
+++ b/clang/test/SemaCXX/matrix-type.cpp
@@ -29,101 +29,3 @@ void matrix_unsupported_element_type() {
   using matrix3_t = bool __attribute__((matrix_type(1, 1)));     // expected-error{{invalid matrix element type 'bool'}}
   using matrix4_t = TestEnum __attribute__((matrix_type(1, 1))); // expected-error{{invalid matrix element type 'TestEnum'}}
 }
-
-template <typename T> // expected-note{{declared here}}
-void matrix_template_1() {
-  using matrix1_t = float __attribute__((matrix_type(T, T))); // expected-error{{'T' does not refer to a value}}
-}
-
-template <class C> // expected-note{{declared here}}
-void matrix_template_2() {
-  using matrix1_t = float __attribute__((matrix_type(C, C))); // expected-error{{'C' does not refer to a value}}
-}
-
-template <unsigned Rows, unsigned Cols>
-void matrix_template_3() {
-  using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{zero matrix size}}
-}
-
-void instantiate_template_3() {
-  matrix_template_3<1, 10>();
-  matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0, 10>' requested here}}
-}
-
-template <int Rows, unsigned Cols>
-void matrix_template_4() {
-  using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{matrix row size too large}}
-}
-
-void instantiate_template_4() {
-  matrix_template_4<2, 10>();
-  matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10>' requested here}}
-}
-
-template <class T, unsigned long R, unsigned long C>
-using matrix = T __attribute__((matrix_type(R, C)));
-
-template <class T, unsigned long R>
-void use_matrix(matrix<T, R, 10> &m) {}
-// expected-note at -1 {{candidate function [with T = float, R = 10]}}
-
-template <class T, unsigned long C>
-void use_matrix(matrix<T, 10, C> &m) {}
-// expected-note at -1 {{candidate function [with T = float, C = 10]}}
-
-void test_ambigous_deduction1() {
-  matrix<float, 10, 10> m;
-  use_matrix(m);
-  // expected-error at -1 {{call to 'use_matrix' is ambiguous}}
-}
-
-template <class T, long R>
-void type_conflict(matrix<T, R, 10> &m, T x) {}
-// expected-note at -1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('float' vs. 'char *')}}
-
-void test_type_conflict(char *p) {
-  matrix<float, 10, 10> m;
-  type_conflict(m, p);
-  // expected-error at -1 {{no matching function for call to 'type_conflict'}}
-}
-
-template <unsigned long R, unsigned long C>
-matrix<float, R + 1, C + 2> use_matrix_2(matrix<int, R, C> &m) {}
-// expected-note at -1 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}}
-// expected-note at -2 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}}
-
-template <unsigned long R, unsigned long C>
-void use_matrix_2(matrix<int, R + 2, C / 2> &m1, matrix<float, R, C> &m2) {}
-// expected-note at -1 {{candidate function [with R = 3, C = 11] not viable: no known conversion from 'matrix<int, 5, 6>' (aka 'int __attribute__((matrix_type(5, 6)))') to 'matrix<int, 3UL + 2, 11UL / 2> &' (aka 'int  __attribute__((matrix_type(5, 5)))&') for 1st argument}}
-// expected-note at -2 {{candidate template ignored: deduced type 'matrix<float, 3UL, 4UL>' of 2nd parameter does not match adjusted type 'matrix<int, 3, 4>' of argument [with R = 3, C = 4]}}
-
-template <typename T, unsigned long R, unsigned long C>
-void use_matrix_2(matrix<T, R + C, C> &m1, matrix<T, R, C - R> &m2) {}
-// expected-note at -1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}}
-// expected-note at -2 {{candidate template ignored: deduced type 'matrix<[...], 3UL + 4UL, 4UL>' of 1st parameter does not match adjusted type 'matrix<[...], 3, 4>' of argument [with T = int, R = 3, C = 4]}}
-
-template <typename T, unsigned long R>
-void use_matrix_3(matrix<T, R - 2, R> &m) {}
-// expected-note at -1 {{candidate template ignored: deduced type 'matrix<[...], 5UL - 2, 5UL>' of 1st parameter does not match adjusted type 'matrix<[...], 5, 5>' of argument [with T = unsigned int, R = 5]}}
-
-void test_use_matrix_2() {
-  matrix<int, 5, 6> m1;
-  matrix<float, 5, 8> r1 = use_matrix_2(m1);
-  // expected-error at -1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 5UL + 1, 6UL + 2>'}}
-
-  matrix<int, 4, 5> m2;
-  matrix<float, 5, 8> r2 = use_matrix_2(m2);
-  // expected-error at -1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 4UL + 1, 5UL + 2>'}}
-
-  matrix<float, 3, 11> m3;
-  use_matrix_2(m1, m3);
-  // expected-error at -1 {{no matching function for call to 'use_matrix_2'}}
-
-  matrix<int, 3, 4> m4;
-  use_matrix_2(m4, m4);
-  // expected-error at -1 {{no matching function for call to 'use_matrix_2'}}
-
-  matrix<unsigned, 5, 5> m5;
-  use_matrix_3(m5);
-  // expected-error at -1 {{no matching function for call to 'use_matrix_3'}}
-}

diff  --git a/clang/test/SemaTemplate/matrix-type.cpp b/clang/test/SemaTemplate/matrix-type.cpp
new file mode 100644
index 000000000000..0ced57c71aa8
--- /dev/null
+++ b/clang/test/SemaTemplate/matrix-type.cpp
@@ -0,0 +1,188 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fenable-matrix %s
+
+template <typename T> // expected-note{{declared here}}
+void matrix_template_1() {
+  using matrix1_t = float __attribute__((matrix_type(T, T))); // expected-error{{'T' does not refer to a value}}
+}
+
+template <class C> // expected-note{{declared here}}
+void matrix_template_2() {
+  using matrix1_t = float __attribute__((matrix_type(C, C))); // expected-error{{'C' does not refer to a value}}
+}
+
+template <unsigned Rows, unsigned Cols>
+void matrix_template_3() {
+  using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{zero matrix size}}
+}
+
+void instantiate_template_3() {
+  matrix_template_3<1, 10>();
+  matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0, 10>' requested here}}
+}
+
+template <int Rows, unsigned Cols>
+void matrix_template_4() {
+  using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{matrix row size too large}}
+}
+
+void instantiate_template_4() {
+  matrix_template_4<2, 10>();
+  matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10>' requested here}}
+}
+
+template <class T, unsigned long R, unsigned long C>
+using matrix = T __attribute__((matrix_type(R, C)));
+
+template <class T, unsigned long R>
+void use_matrix(matrix<T, R, 10> &m) {}
+// expected-note at -1 {{candidate function [with T = float, R = 10]}}
+
+template <class T, unsigned long C>
+void use_matrix(matrix<T, 10, C> &m) {}
+// expected-note at -1 {{candidate function [with T = float, C = 10]}}
+
+void test_ambigous_deduction1() {
+  matrix<float, 10, 10> m;
+  use_matrix(m);
+  // expected-error at -1 {{call to 'use_matrix' is ambiguous}}
+}
+
+template <class T, long R>
+void type_conflict(matrix<T, R, 10> &m, T x) {}
+// expected-note at -1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('float' vs. 'char *')}}
+
+void test_type_conflict(char *p) {
+  matrix<float, 10, 10> m;
+  type_conflict(m, p);
+  // expected-error at -1 {{no matching function for call to 'type_conflict'}}
+}
+
+template <unsigned long R, unsigned long C>
+matrix<float, R + 1, C + 2> use_matrix_2(matrix<int, R, C> &m) {}
+// expected-note at -1 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}}
+// expected-note at -2 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}}
+
+template <unsigned long R, unsigned long C>
+void use_matrix_2(matrix<int, R + 2, C / 2> &m1, matrix<float, R, C> &m2) {}
+// expected-note at -1 {{candidate function [with R = 3, C = 11] not viable: no known conversion from 'matrix<int, 5, 6>' (aka 'int __attribute__((matrix_type(5, 6)))') to 'matrix<int, 3UL + 2, 11UL / 2> &' (aka 'int  __attribute__((matrix_type(5, 5)))&') for 1st argument}}
+// expected-note at -2 {{candidate template ignored: deduced type 'matrix<float, 3UL, 4UL>' of 2nd parameter does not match adjusted type 'matrix<int, 3, 4>' of argument [with R = 3, C = 4]}}
+
+template <typename T, unsigned long R, unsigned long C>
+void use_matrix_2(matrix<T, R + C, C> &m1, matrix<T, R, C - R> &m2) {}
+// expected-note at -1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}}
+// expected-note at -2 {{candidate template ignored: deduced type 'matrix<[...], 3UL + 4UL, 4UL>' of 1st parameter does not match adjusted type 'matrix<[...], 3, 4>' of argument [with T = int, R = 3, C = 4]}}
+
+template <typename T, unsigned long R>
+void use_matrix_3(matrix<T, R - 2, R> &m) {}
+// expected-note at -1 {{candidate template ignored: deduced type 'matrix<[...], 5UL - 2, 5UL>' of 1st parameter does not match adjusted type 'matrix<[...], 5, 5>' of argument [with T = unsigned int, R = 5]}}
+
+void test_use_matrix_2() {
+  matrix<int, 5, 6> m1;
+  matrix<float, 5, 8> r1 = use_matrix_2(m1);
+  // expected-error at -1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 5UL + 1, 6UL + 2>'}}
+
+  matrix<int, 4, 5> m2;
+  matrix<float, 5, 8> r2 = use_matrix_2(m2);
+  // expected-error at -1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 4UL + 1, 5UL + 2>'}}
+
+  matrix<float, 3, 11> m3;
+  use_matrix_2(m1, m3);
+  // expected-error at -1 {{no matching function for call to 'use_matrix_2'}}
+
+  matrix<int, 3, 4> m4;
+  use_matrix_2(m4, m4);
+  // expected-error at -1 {{no matching function for call to 'use_matrix_2'}}
+
+  matrix<unsigned, 5, 5> m5;
+  use_matrix_3(m5);
+  // expected-error at -1 {{no matching function for call to 'use_matrix_3'}}
+}
+template <typename T, unsigned R, unsigned C>
+struct make1 {
+  typedef T __attribute__((matrix_type(R, C))) type;
+};
+
+void test_make1() {
+  make1<int, 5, 4>::type x;
+}
+
+template <typename T, unsigned R, unsigned C>
+struct make2 {
+  typedef T __attribute__((matrix_type(R, C))) type; // expected-error{{zero matrix size}}
+};
+
+int test_make2() {
+  make2<int, 0, 1> x; // expected-note{{in instantiation of}}
+}
+
+template <typename T, unsigned R, unsigned C>
+struct make3 {
+  typedef T __attribute__((matrix_type(R, C))) type; // expected-error{{invalid matrix element type 's'}}
+};
+
+struct s {};
+
+int test_make3() {
+  make3<s, 3, 3> x; // expected-note{{in instantiation of}}
+}
+
+template <typename T, T R, unsigned C>
+struct make4 {
+  typedef T __attribute__((matrix_type(R, C))) type;
+};
+
+int test_make4() {
+  make4<int, 4, 5>::type x;
+}
+
+typedef int *int_ptr;
+template <unsigned R, unsigned C>
+struct make5 {
+  typedef int_ptr __attribute__((matrix_type(R, C))) type; // expected-error{{invalid matrix element type}}
+};
+
+template <int R, unsigned C>
+struct make6 {
+  typedef int __attribute__((matrix_type(R, C))) type;
+};
+
+int test_make6() {
+  make6<4, 4>::type x;
+
+  make6<2, 2>::type y;
+}
+
+namespace Deduction {
+template <typename T>
+struct X0;
+
+template <typename T, unsigned N>
+struct X0<T __attribute__((matrix_type(N, 3)))> {
+  static const unsigned value = 0;
+};
+
+template <typename T>
+struct X0<T __attribute__((matrix_type(4, 3)))> {
+  static const unsigned value = 1;
+};
+
+template <unsigned N>
+struct X0<float __attribute__((matrix_type(N, 3)))> {
+  static const unsigned value = 2;
+};
+
+template <>
+struct X0<float __attribute__((matrix_type(4, 3)))> {
+  static const unsigned value = 3;
+};
+
+typedef int __attribute__((matrix_type(2, 3))) int2;
+typedef int __attribute__((matrix_type(4, 3))) int4;
+typedef float __attribute__((matrix_type(2, 3))) float2;
+typedef float __attribute__((matrix_type(4, 3))) float4;
+
+int array0[X0<int2>::value == 0 ? 1 : -1];
+int array1[X0<int4>::value == 1 ? 1 : -1];
+int array2[X0<float2>::value == 2 ? 1 : -1];
+int array3[X0<float4>::value == 3 ? 1 : -1];
+} // namespace Deduction


        


More information about the cfe-commits mailing list