Commit eedb990a by Paolo Carlini Committed by Paolo Carlini

decl.c (compute_array_index_type_loc): New, like the current…

decl.c (compute_array_index_type_loc): New, like the current compute_array_index_type but takes a location_t too.

/cp
2018-11-29  Paolo Carlini  <paolo.carlini@oracle.com>

	* decl.c (compute_array_index_type_loc): New, like the current
	compute_array_index_type but takes a location_t too.
	(compute_array_index_type): Forward to the latter.
	(create_array_type_for_decl): Use compute_array_index_type_loc.

/testsuite
2018-11-29  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/cpp0x/constexpr-base6b.C: New.
	* g++.dg/cpp0x/constexpr-47969.C: Test locations too.
	* g++.dg/cpp0x/constexpr-48324.C: Likewise.
	* g++.dg/cpp0x/constexpr-ex2.C: Likewise.
	* g++.dg/cpp0x/scoped_enum2.C: Likewise.
	* g++.dg/cpp1y/pr63996.C: Likewise.
	* g++.dg/ext/constexpr-vla5.C: Likewise.
	* g++.dg/ext/stmtexpr15.C: Likewise.
	* g++.dg/ext/vla1.C: Likewise.
	* g++.dg/other/fold1.C: Likewise.
	* g++.dg/parse/array-size2.C: Likewise.
	* g++.dg/parse/crash36.C: Likewise.
	* g++.dg/ubsan/pr81530.C: Likewise.
	* g++.dg/warn/Wvla-1.C: Likewise.
	* g++.dg/warn/Wvla-2.C: Likewise.
	* g++.old-deja/g++.brendan/array1.C: Likewise.
	* g++.old-deja/g++.bugs/900402_02.C: Likewise.
	* g++.old-deja/g++.law/init3.C: Likewise.
	* g++.old-deja/g++.mike/p6149.C: Likewise.

From-SVN: r266645
parent 3ded6ffd
2018-11-29 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (compute_array_index_type_loc): New, like the current
compute_array_index_type but takes a location_t too.
(compute_array_index_type): Forward to the latter.
(create_array_type_for_decl): Use compute_array_index_type_loc.
2018-11-29 David Malcolm <dmalcolm@redhat.com> 2018-11-29 David Malcolm <dmalcolm@redhat.com>
PR c++/88121 PR c++/88121
......
...@@ -9621,8 +9621,9 @@ fold_sizeof_expr (tree t) ...@@ -9621,8 +9621,9 @@ fold_sizeof_expr (tree t)
an appropriate index type for the array. If non-NULL, NAME is an appropriate index type for the array. If non-NULL, NAME is
the name of the entity being declared. */ the name of the entity being declared. */
tree static tree
compute_array_index_type (tree name, tree size, tsubst_flags_t complain) compute_array_index_type_loc (location_t name_loc, tree name, tree size,
tsubst_flags_t complain)
{ {
tree itype; tree itype;
tree osize = size; tree osize = size;
...@@ -9630,6 +9631,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) ...@@ -9630,6 +9631,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
if (error_operand_p (size)) if (error_operand_p (size))
return error_mark_node; return error_mark_node;
location_t loc = cp_expr_loc_or_loc (size, name ? name_loc : input_location);
if (!type_dependent_expression_p (size)) if (!type_dependent_expression_p (size))
{ {
osize = size = mark_rvalue_use (size); osize = size = mark_rvalue_use (size);
...@@ -9658,9 +9661,10 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) ...@@ -9658,9 +9661,10 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
if (!(complain & tf_error)) if (!(complain & tf_error))
return error_mark_node; return error_mark_node;
if (name) if (name)
error ("size of array %qD has non-integral type %qT", name, type); error_at (loc, "size of array %qD has non-integral type %qT",
name, type);
else else
error ("size of array has non-integral type %qT", type); error_at (loc, "size of array has non-integral type %qT", type);
size = integer_one_node; size = integer_one_node;
} }
} }
...@@ -9689,8 +9693,14 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) ...@@ -9689,8 +9693,14 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
{ {
tree folded = cp_fully_fold (size); tree folded = cp_fully_fold (size);
if (TREE_CODE (folded) == INTEGER_CST) if (TREE_CODE (folded) == INTEGER_CST)
pedwarn (input_location, OPT_Wpedantic, {
"size of array is not an integral constant-expression"); if (name)
pedwarn (loc, OPT_Wpedantic, "size of array %qD is not an "
"integral constant-expression", name);
else
pedwarn (loc, OPT_Wpedantic,
"size of array is not an integral constant-expression");
}
/* Use the folded result for VLAs, too; it will have resolved /* Use the folded result for VLAs, too; it will have resolved
SIZEOF_EXPR. */ SIZEOF_EXPR. */
size = folded; size = folded;
...@@ -9706,9 +9716,9 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) ...@@ -9706,9 +9716,9 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
return error_mark_node; return error_mark_node;
if (name) if (name)
error ("size of array %qD is negative", name); error_at (loc, "size of array %qD is negative", name);
else else
error ("size of array is negative"); error_at (loc, "size of array is negative");
size = integer_one_node; size = integer_one_node;
} }
/* As an extension we allow zero-sized arrays. */ /* As an extension we allow zero-sized arrays. */
...@@ -9722,9 +9732,11 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) ...@@ -9722,9 +9732,11 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
else if (in_system_header_at (input_location)) else if (in_system_header_at (input_location))
/* Allow them in system headers because glibc uses them. */; /* Allow them in system headers because glibc uses them. */;
else if (name) else if (name)
pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name); pedwarn (loc, OPT_Wpedantic,
"ISO C++ forbids zero-size array %qD", name);
else else
pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array"); pedwarn (loc, OPT_Wpedantic,
"ISO C++ forbids zero-size array");
} }
} }
else if (TREE_CONSTANT (size) else if (TREE_CONSTANT (size)
...@@ -9737,24 +9749,27 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) ...@@ -9737,24 +9749,27 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
return error_mark_node; return error_mark_node;
/* `(int) &fn' is not a valid array bound. */ /* `(int) &fn' is not a valid array bound. */
if (name) if (name)
error ("size of array %qD is not an integral constant-expression", error_at (loc,
name); "size of array %qD is not an integral constant-expression",
name);
else else
error ("size of array is not an integral constant-expression"); error_at (loc, "size of array is not an integral constant-expression");
size = integer_one_node; size = integer_one_node;
} }
else if (pedantic && warn_vla != 0) else if (pedantic && warn_vla != 0)
{ {
if (name) if (name)
pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name); pedwarn (name_loc, OPT_Wvla,
"ISO C++ forbids variable length array %qD", name);
else else
pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array"); pedwarn (input_location, OPT_Wvla,
"ISO C++ forbids variable length array");
} }
else if (warn_vla > 0) else if (warn_vla > 0)
{ {
if (name) if (name)
warning (OPT_Wvla, warning_at (name_loc, OPT_Wvla,
"variable length array %qD is used", name); "variable length array %qD is used", name);
else else
warning (OPT_Wvla, warning (OPT_Wvla,
"variable length array is used"); "variable length array is used");
...@@ -9821,6 +9836,12 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) ...@@ -9821,6 +9836,12 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
return itype; return itype;
} }
tree
compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
{
return compute_array_index_type_loc (input_location, name, size, complain);
}
/* Returns the scope (if any) in which the entity declared by /* Returns the scope (if any) in which the entity declared by
DECLARATOR will be located. If the entity was declared with an DECLARATOR will be located. If the entity was declared with an
unqualified name, NULL_TREE is returned. */ unqualified name, NULL_TREE is returned. */
...@@ -9922,7 +9943,8 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc) ...@@ -9922,7 +9943,8 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc)
/* Figure out the index type for the array. */ /* Figure out the index type for the array. */
if (size) if (size)
itype = compute_array_index_type (name, size, tf_warning_or_error); itype = compute_array_index_type_loc (loc, name, size,
tf_warning_or_error);
/* [dcl.array] /* [dcl.array]
T is called the array element type; this type shall not be [...] an T is called the array element type; this type shall not be [...] an
......
2018-11-29 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/cpp0x/constexpr-base6b.C: New.
* g++.dg/cpp0x/constexpr-47969.C: Test locations too.
* g++.dg/cpp0x/constexpr-48324.C: Likewise.
* g++.dg/cpp0x/constexpr-ex2.C: Likewise.
* g++.dg/cpp0x/scoped_enum2.C: Likewise.
* g++.dg/cpp1y/pr63996.C: Likewise.
* g++.dg/ext/constexpr-vla5.C: Likewise.
* g++.dg/ext/stmtexpr15.C: Likewise.
* g++.dg/ext/vla1.C: Likewise.
* g++.dg/other/fold1.C: Likewise.
* g++.dg/parse/array-size2.C: Likewise.
* g++.dg/parse/crash36.C: Likewise.
* g++.dg/ubsan/pr81530.C: Likewise.
* g++.dg/warn/Wvla-1.C: Likewise.
* g++.dg/warn/Wvla-2.C: Likewise.
* g++.old-deja/g++.brendan/array1.C: Likewise.
* g++.old-deja/g++.bugs/900402_02.C: Likewise.
* g++.old-deja/g++.law/init3.C: Likewise.
* g++.old-deja/g++.mike/p6149.C: Likewise.
2018-11-29 David Malcolm <dmalcolm@redhat.com> 2018-11-29 David Malcolm <dmalcolm@redhat.com>
PR c++/88121 PR c++/88121
......
...@@ -8,4 +8,5 @@ struct A ...@@ -8,4 +8,5 @@ struct A
constexpr A a = A(); constexpr A a = A();
int ar[a]; // { dg-error "could not convert|has non-integral type" } int ar[a]; // { dg-error "could not convert" }
// { dg-error "5:size of array .ar. has non-integral" "" { target c++11 } .-1 }
...@@ -10,4 +10,4 @@ constexpr const int& to_ref(int i) { ...@@ -10,4 +10,4 @@ constexpr const int& to_ref(int i) {
return S(i).val; // { dg-warning "reference to temporary" } return S(i).val; // { dg-warning "reference to temporary" }
} }
constexpr int ary[to_ref(98)] = { }; // { dg-error "not an integral" } constexpr int ary[to_ref(98)] = { }; // { dg-error "25:size of array .ary. is not an integral" }
// CWG issue 2310
// { dg-do compile { target c++11 } }
template<typename A, typename B> struct check_derived_from {
static A a;
static constexpr B *p = &a; // { dg-error "cannot convert" }
int ar[p-p+1]; // { dg-error "13:size of array is not an integral constant-expression" }
};
struct W { int i; };
struct Z : W
{
check_derived_from<Z, W> cdf;
};
...@@ -18,5 +18,5 @@ constexpr A a = 42; ...@@ -18,5 +18,5 @@ constexpr A a = 42;
X<a> x; // OK: unique conversion to int X<a> x; // OK: unique conversion to int
int ar[X<a>::i]; // also OK int ar[X<a>::i]; // also OK
int ary[a]; // { dg-error "could not convert|ambiguous|conversion|array" } ambiguous conversion int ary[a]; // { dg-error "could not convert" } ambiguous conversion
// { dg-error "5:size of array .ary. has non-integral" "" { target c++11 } .-1 }
...@@ -4,7 +4,8 @@ enum class E { e = 10 }; ...@@ -4,7 +4,8 @@ enum class E { e = 10 };
enum E2 { e2 = 10 }; enum E2 { e2 = 10 };
struct C { struct C {
int arr[E::e]; // { dg-error "could not convert|non-integral type" } int arr[E::e]; // { dg-error "could not convert" }
// { dg-error "7:size of array .arr. has non-integral" "" { target c++11 } .-1 }
int arr2[E2::e2]; // OK int arr2[E2::e2]; // OK
int i: E::e; // { dg-error "could not convert|non-integral type" } int i: E::e; // { dg-error "could not convert|non-integral type" }
int i2: E2::e2; // OK int i2: E2::e2; // OK
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
constexpr int constexpr int
foo (int i) foo (int i)
{ {
int a[i] = { }; // { dg-error "forbids variable length" } int a[i] = { }; // { dg-error "7:ISO C\\+\\+ forbids variable length array .a" }
} }
constexpr int j = foo (1); // { dg-error "flows off the end|in .constexpr. expansion of" } constexpr int j = foo (1); // { dg-error "flows off the end|in .constexpr. expansion of" }
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
void foo(int i) void foo(int i)
{ {
constexpr char x[i] = ""; // { dg-error "18:.constexpr. variable .x. has variably-modified type" } constexpr char x[i] = ""; // { dg-error "18:.constexpr. variable .x. has variably-modified type" }
// { dg-error "ISO C\\+\\+ forbids variable length array .x" "" { target c++11 } .-1 } // { dg-error "18:ISO C\\+\\+ forbids variable length array .x" "" { target c++11 } .-1 }
} }
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
void foo() void foo()
{ {
int x[({ return; })]; // { dg-error "could not convert|non-integral" } int x[({ return; })]; // { dg-error "could not convert" }
// { dg-error "12:size of array .x. has non-integral" "" { target *-*-* } .-1 }
} }
...@@ -9,7 +9,7 @@ class A { A (int); }; ...@@ -9,7 +9,7 @@ class A { A (int); };
A::A (int i) A::A (int i)
{ {
int ar[1][i]; // { dg-error "array" } int ar[1][i]; // { dg-error "7:ISO C\\+\\+ forbids variable length array .ar" }
ar[0][0] = 0; ar[0][0] = 0;
} }
...@@ -19,7 +19,8 @@ class B { B (int); }; ...@@ -19,7 +19,8 @@ class B { B (int); };
B::B (int i) B::B (int i)
{ {
struct S { struct S {
int ar[1][i]; // { dg-error "array" } int ar[1][i]; // { dg-error "9:size of array .ar. is not an integral" "" { target c++11 } }
// { dg-error "array bound" "" { target c++98_only } .-1 }
} s; } s;
s.ar[0][0] = 0; // { dg-prune-output "no member" } s.ar[0][0] = 0; // { dg-prune-output "no member" }
......
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
struct A struct A
{ {
static const int i = i; // { dg-error "not declared" } static const int i = i; // { dg-error "not declared" }
int x[i]; // { dg-error "constant-expression|narrowing conversion" } int x[i]; // { dg-error "9:size of array .x. is not an integral constant-expression" }
}; };
...@@ -14,7 +14,7 @@ extern void bar (char *, char *); ...@@ -14,7 +14,7 @@ extern void bar (char *, char *);
void void
foo (void) foo (void)
{ {
char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "constant|narrowing conversion" } char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "40:size of array .g. is not an integral constant-expression" }
char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; // { dg-error "constant" } char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; // { dg-error "10:size of array .h. is not an integral constant-expression" }
bar (g, h); bar (g, h);
} }
...@@ -9,4 +9,4 @@ template <typename... T> struct A // { dg-warning "variadic templates" } ...@@ -9,4 +9,4 @@ template <typename... T> struct A // { dg-warning "variadic templates" }
static const int i = sizeof (++t); // { dg-error "was not declared in this scope" } static const int i = sizeof (++t); // { dg-error "was not declared in this scope" }
}; };
int x[A <int>::i]; // { dg-error "constant-expression" } int x[A <int>::i]; // { dg-error "5:size of array .x. is not an integral constant-expression" }
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-fsanitize=undefined" } */ /* { dg-options "-fsanitize=undefined" } */
int a[(long) 4e20]; /* { dg-error "size of array .a. is (too large|negative)" } */ int a[(long) 4e20]; /* { dg-error "7:size of array .a. is (too large|negative)" } */
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
void func (int i) void func (int i)
{ {
int array[i]; /* { dg-warning "variable length array 'array' is used" } */ int array[i]; /* { dg-warning "7:variable length array 'array' is used" } */
} }
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
void func (int i) void func (int i)
{ {
int array[i]; /* { dg-error "ISO C.* forbids variable.* array 'array'" } */ int array[i]; /* { dg-error "7:ISO C.* forbids variable.* array 'array'" } */
} }
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// GROUPS passed array-bindings // GROUPS passed array-bindings
extern "C" int printf (const char *, ...); extern "C" int printf (const char *, ...);
char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)]; // { dg-error "" } overflow in array dimension.* char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)]; // { dg-error "39:size of array .array. is negative" } overflow in array dimension.*
int main () { printf ("PASS\n"); return 0; } int main () { printf ("PASS\n"); return 0; }
...@@ -6,17 +6,17 @@ ...@@ -6,17 +6,17 @@
// keywords: arrays, array bound, zero length // keywords: arrays, array bound, zero length
typedef int array_type[0]; // { dg-error "zero-size array" } typedef int array_type[0]; // { dg-error "13:ISO C\\+\\+ forbids zero-size array" }
int array_object_1[0]; // { dg-error "zero-size array" } int array_object_1[0]; // { dg-error "5:ISO C\\+\\+ forbids zero-size array" }
void function_0 (int formal_array[0]) // { dg-error "zero-size array" } void function_0 (int formal_array[0]) // { dg-error "22:ISO C\\+\\+ forbids zero-size array" }
{ {
} }
void function_2 () void function_2 ()
{ {
int local_object_array_0[0]; // { dg-error "zero-size array" } int local_object_array_0[0]; // { dg-error "7:ISO C\\+\\+ forbids zero-size array" }
} }
int main () { return 0; } int main () { return 0; }
...@@ -8,5 +8,5 @@ ...@@ -8,5 +8,5 @@
int main() { int main() {
int offset; int offset;
char buf[offset]=""; // { dg-error "" } ansi forbids variable arrays char buf[offset]=""; // { dg-error "6:ISO C\\+\\+ forbids variable length array .buf" } ansi forbids variable arrays
} }
// { dg-do assemble } // { dg-do assemble }
// prms-id: 6149 // prms-id: 6149
int a[3 - sizeof(double)]; // { dg-error "" } int a[3 - sizeof(double)]; // { dg-error "9:size of array .a. is negative" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment