diff options
author | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-09 06:18:29 +0000 |
---|---|---|
committer | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-09 06:18:29 +0000 |
commit | 41ed701aa7962118609ab7a37c741dd165a1e1c0 (patch) | |
tree | 41770fbb2dff0d56518b79bce3dd01c52d1b2759 | |
parent | 913a7575316e16a95adf81eb285e4a77bd66b0a4 (diff) | |
download | gcc-41ed701aa7962118609ab7a37c741dd165a1e1c0.tar.gz |
2012-10-09 Marc Glisse <marc.glisse@inria.fr>
PR c++/54427
c/
* c-typeck.c: Include c-common.h.
(enum stv_conv): Moved to c-common.h.
(scalar_to_vector): Moved to c-common.c.
(build_binary_op): Adapt to scalar_to_vector's new prototype.
* Make-lang.in: c-typeck.c depends on c-common.h.
c-family/
* c-common.c (scalar_to_vector): Moved from c-typeck.c. Support
more operations. Make error messages optional.
* c-common.h (enum stv_conv): Moved from c-typeck.c.
(scalar_to_vector): Declare.
cp/
* typeck.c (cp_build_binary_op): Handle mixed scalar-vector
operations.
[LSHIFT_EXPR, RSHIFT_EXPR]: Likewise.
gcc/
* fold-const.c (fold_binary_loc): Use build_zero_cst instead of
build_int_cst for a potential vector.
testsuite/
* c-c++-common/vector-scalar.c: New testcase.
* g++.dg/ext/vector18.C: New testcase.
* g++.dg/ext/vector5.C: This is not an error anymore.
* gcc.dg/init-vec-1.c: Move ...
* c-c++-common/init-vec-1.c: ... here. Adapt error message.
* gcc.c-torture/execute/vector-shift1.c: Move ...
* c-c++-common/torture/vector-shift1.c: ... here.
* gcc.dg/scal-to-vec1.c: Move ...
* c-c++-common/scal-to-vec1.c: ... here. Avoid narrowing for
C++11. Adapt error messages.
* gcc.dg/convert-vec-1.c: Move ...
* c-c++-common/convert-vec-1.c: ... here.
* gcc.dg/scal-to-vec2.c: Move ...
* c-c++-common/scal-to-vec2.c: ... here.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192238 138bc75d-0d04-0410-961f-82ee72b054a4
19 files changed, 252 insertions, 107 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3879f3882cb..661af2a3a07 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * fold-const.c (fold_binary_loc): Use build_zero_cst instead of + build_int_cst for a potential vector. + 2012-10-08 Uros Bizjak <ubizjak@gmail.com> * config/i386/atom.md (atom_sse_4): Merge atom_sse_attr attibutes. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 36bab2ee23e..c86eb69a403 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * c-common.c (scalar_to_vector): Moved from c-typeck.c. Support + more operations. Make error messages optional. + * c-common.h (enum stv_conv): Moved from c-typeck.c. + (scalar_to_vector): Declare. + 2012-10-08 Jason Merrill <jason@redhat.com> * c-common.c (c_common_reswords): Add thread_local. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index bb18c39cd6b..edd25aa6060 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -11253,6 +11253,109 @@ convert_vector_to_pointer_for_subscript (location_t loc, } } +/* Determine which of the operands, if any, is a scalar that needs to be + converted to a vector, for the range of operations. */ +enum stv_conv +scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1, + bool complain) +{ + tree type0 = TREE_TYPE (op0); + tree type1 = TREE_TYPE (op1); + bool integer_only_op = false; + enum stv_conv ret = stv_firstarg; + + gcc_assert (TREE_CODE (type0) == VECTOR_TYPE + || TREE_CODE (type1) == VECTOR_TYPE); + switch (code) + { + /* Most GENERIC binary expressions require homogeneous arguments. + LSHIFT_EXPR and RSHIFT_EXPR are exceptions and accept a first + argument that is a vector and a second one that is a scalar, so + we never return stv_secondarg for them. */ + case RSHIFT_EXPR: + case LSHIFT_EXPR: + if (TREE_CODE (type0) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) + { + if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) + { + if (complain) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", type0, type1); + return stv_error; + } + else + return stv_firstarg; + } + break; + + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: + case BIT_AND_EXPR: + integer_only_op = true; + /* ... fall through ... */ + + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case EXACT_DIV_EXPR: + case TRUNC_MOD_EXPR: + case FLOOR_MOD_EXPR: + case RDIV_EXPR: + case EQ_EXPR: + case NE_EXPR: + case LE_EXPR: + case GE_EXPR: + case LT_EXPR: + case GT_EXPR: + /* What about UNLT_EXPR? */ + if (TREE_CODE (type0) == VECTOR_TYPE) + { + tree tmp; + ret = stv_secondarg; + /* Swap TYPE0 with TYPE1 and OP0 with OP1 */ + tmp = type0; type0 = type1; type1 = tmp; + tmp = op0; op0 = op1; op1 = tmp; + } + + if (TREE_CODE (type0) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) + { + if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) + { + if (complain) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", type0, type1); + return stv_error; + } + return ret; + } + else if (!integer_only_op + /* Allow integer --> real conversion if safe. */ + && (TREE_CODE (type0) == REAL_TYPE + || TREE_CODE (type0) == INTEGER_TYPE) + && SCALAR_FLOAT_TYPE_P (TREE_TYPE (type1))) + { + if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) + { + if (complain) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", type0, type1); + return stv_error; + } + return ret; + } + default: + break; + } + + return stv_nothing; +} + /* Return true iff ALIGN is an integral constant that is a fundamental alignment, as defined by [basic.align] in the c++-11 specifications. diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 5b23bd3c2fa..481c3ed0617 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1123,4 +1123,15 @@ extern tree build_userdef_literal (tree suffix_id, tree value, tree num_string); extern void convert_vector_to_pointer_for_subscript (location_t, tree*, tree); +/* Possibe cases of scalar_to_vector conversion. */ +enum stv_conv { + stv_error, /* Error occured. */ + stv_nothing, /* Nothing happened. */ + stv_firstarg, /* First argument must be expanded. */ + stv_secondarg /* Second argument must be expanded. */ +}; + +extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code, + tree op0, tree op1, bool); + #endif /* ! GCC_C_COMMON_H */ diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 257b752cca4..93c72f0c69f 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,12 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * c-typeck.c: Include c-common.h. + (enum stv_conv): Moved to c-common.h. + (scalar_to_vector): Moved to c-common.c. + (build_binary_op): Adapt to scalar_to_vector's new prototype. + * Make-lang.in: c-typeck.c depends on c-common.h. + 2012-10-04 Arnaud Charlet <charlet@adacore.com> * c-decl.c (c_write_global_declarations): Fix handling of diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in index a39c91cc0c6..93b8f64872d 100644 --- a/gcc/c/Make-lang.in +++ b/gcc/c/Make-lang.in @@ -192,5 +192,5 @@ c/c-parser.o : c/c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ c/c-typeck.o : c/c-typeck.c c/c-lang.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(C_TREE_H) $(TARGET_H) $(FLAGS_H) intl.h \ langhooks.h tree-iterator.h $(BITMAP_H) $(GIMPLE_H) \ - c-family/c-objc.h + c-family/c-objc.h c-family/c-common.h diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 5b4ad285874..ae6b3484b95 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "bitmap.h" #include "gimple.h" #include "c-family/c-objc.h" +#include "c-family/c-common.h" /* Possible cases of implicit bad conversions. Used to select diagnostic messages in convert_for_assignment. */ @@ -50,14 +51,6 @@ enum impl_conv { ic_return }; -/* Possibe cases of scalar_to_vector conversion. */ -enum stv_conv { - stv_error, /* Error occured. */ - stv_nothing, /* Nothing happened. */ - stv_firstarg, /* First argument must be expanded. */ - stv_secondarg /* Second argument must be expanded. */ -}; - /* The level of nesting inside "__alignof__". */ int in_alignof; @@ -9375,88 +9368,6 @@ push_cleanup (tree decl, tree cleanup, bool eh_only) TREE_OPERAND (stmt, 0) = list; STATEMENT_LIST_STMT_EXPR (list) = stmt_expr; } - -/* Convert scalar to vector for the range of operations. */ -static enum stv_conv -scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1) -{ - tree type0 = TREE_TYPE (op0); - tree type1 = TREE_TYPE (op1); - bool integer_only_op = false; - enum stv_conv ret = stv_firstarg; - - gcc_assert (TREE_CODE (type0) == VECTOR_TYPE - || TREE_CODE (type1) == VECTOR_TYPE); - switch (code) - { - case RSHIFT_EXPR: - case LSHIFT_EXPR: - if (TREE_CODE (type0) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) - { - if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) - { - error_at (loc, "conversion of scalar to vector " - "involves truncation"); - return stv_error; - } - else - return stv_firstarg; - } - break; - - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - integer_only_op = true; - /* ... fall through ... */ - - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case TRUNC_MOD_EXPR: - case RDIV_EXPR: - if (TREE_CODE (type0) == VECTOR_TYPE) - { - tree tmp; - ret = stv_secondarg; - /* Swap TYPE0 with TYPE1 and OP0 with OP1 */ - tmp = type0; type0 = type1; type1 = tmp; - tmp = op0; op0 = op1; op1 = tmp; - } - - if (TREE_CODE (type0) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) - { - if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) - { - error_at (loc, "conversion of scalar to vector " - "involves truncation"); - return stv_error; - } - return ret; - } - else if (!integer_only_op - /* Allow integer --> real conversion if safe. */ - && (TREE_CODE (type0) == REAL_TYPE - || TREE_CODE (type0) == INTEGER_TYPE) - && SCALAR_FLOAT_TYPE_P (TREE_TYPE (type1))) - { - if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) - { - error_at (loc, "conversion of scalar to vector " - "involves truncation"); - return stv_error; - } - return ret; - } - default: - break; - } - - return stv_nothing; -} /* Build a binary-operation expression without default conversions. CODE is the kind of expression to build. @@ -9647,7 +9558,8 @@ build_binary_op (location_t location, enum tree_code code, a vector and another is a scalar -- convert scalar to vector. */ if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE)) { - enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1); + enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1, + true); switch (convert_flag) { diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f4e7e6a1846..4c1d01abc8e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * typeck.c (cp_build_binary_op): Handle mixed scalar-vector + operations. + [LSHIFT_EXPR, RSHIFT_EXPR]: Likewise. + 2012-10-08 Jakub Jelinek <jakub@redhat.com> PR c++/54858 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ae4d0a44589..94e17c5aa00 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3912,6 +3912,40 @@ cp_build_binary_op (location_t location, warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic"); } + /* In case when one of the operands of the binary operation is + a vector and another is a scalar -- convert scalar to vector. */ + if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE)) + { + enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1, + complain & tf_error); + + switch (convert_flag) + { + case stv_error: + return error_mark_node; + case stv_firstarg: + { + op0 = convert (TREE_TYPE (type1), op0); + op0 = build_vector_from_val (type1, op0); + type0 = TREE_TYPE (op0); + code0 = TREE_CODE (type0); + converted = 1; + break; + } + case stv_secondarg: + { + op1 = convert (TREE_TYPE (type0), op1); + op1 = build_vector_from_val (type0, op1); + type1 = TREE_TYPE (op1); + code1 = TREE_CODE (type1); + converted = 1; + break; + } + default: + break; + } + } + switch (code) { case MINUS_EXPR: @@ -4035,7 +4069,13 @@ cp_build_binary_op (location_t location, Also set SHORT_SHIFT if shifting rightward. */ case RSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) + { + result_type = type0; + converted = 1; + } + else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) @@ -4072,7 +4112,13 @@ cp_build_binary_op (location_t location, break; case LSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) + { + result_type = type0; + converted = 1; + } + else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index fd0075c4971..9dabfabcec8 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -12857,7 +12857,7 @@ fold_binary_loc (location_t loc, arg00 = fold_convert_loc (loc, itype, arg00); } return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR, - type, arg00, build_int_cst (itype, 0)); + type, arg00, build_zero_cst (itype)); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 08e0a690283..dc996533ea2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * c-c++-common/vector-scalar.c: New testcase. + * g++.dg/ext/vector18.C: New testcase. + * g++.dg/ext/vector5.C: This is not an error anymore. + * gcc.dg/init-vec-1.c: Move ... + * c-c++-common/init-vec-1.c: ... here. Adapt error message. + * gcc.c-torture/execute/vector-shift1.c: Move ... + * c-c++-common/torture/vector-shift1.c: ... here. + * gcc.dg/scal-to-vec1.c: Move ... + * c-c++-common/scal-to-vec1.c: ... here. Avoid narrowing for + C++11. Adapt error messages. + * gcc.dg/convert-vec-1.c: Move ... + * c-c++-common/convert-vec-1.c: ... here. + * gcc.dg/scal-to-vec2.c: Move ... + * c-c++-common/scal-to-vec2.c: ... here. + 2012-10-08 Marc Glisse <marc.glisse@inria.fr> PR target/54400 diff --git a/gcc/testsuite/gcc.dg/convert-vec-1.c b/gcc/testsuite/c-c++-common/convert-vec-1.c index 49872984073..49872984073 100644 --- a/gcc/testsuite/gcc.dg/convert-vec-1.c +++ b/gcc/testsuite/c-c++-common/convert-vec-1.c diff --git a/gcc/testsuite/gcc.dg/init-vec-1.c b/gcc/testsuite/c-c++-common/init-vec-1.c index 9921b16a91e..68243cd302f 100644 --- a/gcc/testsuite/gcc.dg/init-vec-1.c +++ b/gcc/testsuite/c-c++-common/init-vec-1.c @@ -1,4 +1,4 @@ /* Don't ICE or emit spurious errors when init a vector with a scalar. */ /* { dg-do compile } */ typedef float v2sf __attribute__ ((vector_size (8))); -v2sf a = 0.0; /* { dg-error "incompatible types" } */ +v2sf a = 0.0; /* { dg-error "incompatible types|cannot convert" } */ diff --git a/gcc/testsuite/gcc.dg/scal-to-vec1.c b/gcc/testsuite/c-c++-common/scal-to-vec1.c index 0c1a5093315..beb450db624 100644 --- a/gcc/testsuite/gcc.dg/scal-to-vec1.c +++ b/gcc/testsuite/c-c++-common/scal-to-vec1.c @@ -13,7 +13,7 @@ extern int sint; extern long long sll; int main (int argc, char *argv[]) { - vector(8, short) v0 = {argc, 1,2,3,4,5,6,7}; + vector(8, short) v0 = {(short)argc, 1,2,3,4,5,6,7}; vector(8, short) v1; vector(4, float) f0 = {1., 2., 3., 4.}; @@ -26,18 +26,18 @@ int main (int argc, char *argv[]) { int i = 12; double d = 3.; - v1 = i + v0; /* { dg-error "conversion of scalar to vector" } */ - v1 = 99999 + v0; /* { dg-error "conversion of scalar to vector" } */ + v1 = i + v0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + v1 = 99999 + v0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ - f1 = d + f0; /* { dg-error "conversion of scalar to vector" } */ - f1 = 1.3 + f0; /* { dg-error "conversion of scalar to vector" } */ - f1 = sll + f0; /* { dg-error "conversion of scalar to vector" } */ - f1 = ((int)998769576) + f0; /* { dg-error "conversion of scalar to vector" } */ + f1 = d + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + f1 = 1.3 + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + f1 = sll + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + f1 = ((int)998769576) + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ /* convert.c should take care of this. */ - i1 = sfl + i0; /* { dg-error "can't convert value to a vector" } */ - i1 = 1.5 + i0; /* { dg-error "can't convert value to a vector" } */ - v1 = d + v0; /* { dg-error "can't convert value to a vector" } */ + i1 = sfl + i0; /* { dg-error "can't convert value to a vector|invalid operands" } */ + i1 = 1.5 + i0; /* { dg-error "can't convert value to a vector|invalid operands" } */ + v1 = d + v0; /* { dg-error "can't convert value to a vector|invalid operands" } */ return 0; } diff --git a/gcc/testsuite/gcc.dg/scal-to-vec2.c b/gcc/testsuite/c-c++-common/scal-to-vec2.c index 1897b93e050..1897b93e050 100644 --- a/gcc/testsuite/gcc.dg/scal-to-vec2.c +++ b/gcc/testsuite/c-c++-common/scal-to-vec2.c diff --git a/gcc/testsuite/gcc.c-torture/execute/vector-shift1.c b/gcc/testsuite/c-c++-common/torture/vector-shift1.c index 6041fc3b07e..e6e31daf578 100644 --- a/gcc/testsuite/gcc.c-torture/execute/vector-shift1.c +++ b/gcc/testsuite/c-c++-common/torture/vector-shift1.c @@ -1,3 +1,4 @@ +/* { dg-do run } */ #define vector __attribute__((vector_size(8*sizeof(short)))) int main (int argc, char *argv[]) { diff --git a/gcc/testsuite/c-c++-common/vector-scalar.c b/gcc/testsuite/c-c++-common/vector-scalar.c new file mode 100644 index 00000000000..1b32cc67bdd --- /dev/null +++ b/gcc/testsuite/c-c++-common/vector-scalar.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ + +typedef float vecf __attribute__ ((vector_size (4 * sizeof (float)))); +typedef short veci __attribute__ ((vector_size (8 * sizeof (short)))); + +void f (vecf *d, veci *i) +{ + (void) ((*d *= 2) < 0); + (void) ((((*i - 1) >> 2) != 0) | *i); +} diff --git a/gcc/testsuite/g++.dg/ext/vector18.C b/gcc/testsuite/g++.dg/ext/vector18.C new file mode 100644 index 00000000000..dfffad5af76 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector18.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c++11" } */ + +typedef signed char __attribute__((vector_size(128) )) vec; + +template <class A, class B> +auto f (A *a, B b) -> decltype (*a + b); + +void f (...) {} + +void g (vec *v, long long l) +{ + f (v, l); +} diff --git a/gcc/testsuite/g++.dg/ext/vector5.C b/gcc/testsuite/g++.dg/ext/vector5.C index e5304bcb12d..68f711fe233 100644 --- a/gcc/testsuite/g++.dg/ext/vector5.C +++ b/gcc/testsuite/g++.dg/ext/vector5.C @@ -4,5 +4,5 @@ void foo() { int __attribute__((vector_size(8))) v; - v = 1/v; // { dg-error "invalid operands of types" } + v = 1/v; } |