PR c++/9844, PR c++/13989
PR c++/9844, PR c++/13989 Reviewed by Mark Mitchel. From-SVN: r87971
This commit is contained in:
parent
093942ac67
commit
037cc9c5dc
@ -1,3 +1,18 @@
|
||||
2004-09-21 Fariborz Jahanian <fjahanian@apple.com>
|
||||
PR c++/13989
|
||||
PR c++/9844
|
||||
|
||||
* cp/decl.c (grokfndecl): Add new argument "attrlist", use it
|
||||
to call cplus_decl_attributes.
|
||||
(start_function): Remove call to cplus_decl_attributes.
|
||||
* tree.c (reconstruct_complex_type): Remove extra "this".
|
||||
* cp/cvt.c (ocp_convert): Add support to use type conversion
|
||||
function to vector type.
|
||||
* cp/parser.c (cp_parser_conversion_type_id): Add attributes, if any,
|
||||
to the parsed type.
|
||||
* config/rs6000/rs6000.c (rs6000_handle_altivec_attribute):
|
||||
Add V4SFmode to case statement.
|
||||
|
||||
2004-09-23 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
PR c/16833
|
||||
|
@ -16265,7 +16265,7 @@ rs6000_handle_altivec_attribute (tree *node, tree name, tree args,
|
||||
/* If the user says 'vector int bool', we may be handed the 'bool'
|
||||
attribute _before_ the 'vector' attribute, and so select the proper
|
||||
type in the 'b' case below. */
|
||||
case V4SImode: case V8HImode: case V16QImode: result = type;
|
||||
case V4SImode: case V8HImode: case V16QImode: case V4SFmode: result = type;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
15
gcc/cp/cvt.c
15
gcc/cp/cvt.c
@ -699,7 +699,20 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
|
||||
if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
|
||||
return fold (cp_convert_to_pointer (type, e, false));
|
||||
if (code == VECTOR_TYPE)
|
||||
return fold (convert_to_vector (type, e));
|
||||
{
|
||||
tree in_vtype = TREE_TYPE (e);
|
||||
if (IS_AGGR_TYPE (in_vtype))
|
||||
{
|
||||
tree ret_val;
|
||||
ret_val = build_type_conversion (type, e);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
if (flags & LOOKUP_COMPLAIN)
|
||||
error ("`%#T' used where a `%T' was expected", in_vtype, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
return fold (convert_to_vector (type, e));
|
||||
}
|
||||
if (code == REAL_TYPE || code == COMPLEX_TYPE)
|
||||
{
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (e)))
|
||||
|
@ -63,7 +63,8 @@ static void push_local_name (tree);
|
||||
static tree grok_reference_init (tree, tree, tree, tree *);
|
||||
static tree grokfndecl (tree, tree, tree, tree, tree, int,
|
||||
enum overload_flags, cp_cv_quals,
|
||||
tree, int, int, int, int, int, int, tree);
|
||||
tree, int, int, int, int, int, int, tree,
|
||||
tree *);
|
||||
static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
|
||||
int, int, tree);
|
||||
static void record_unknown_type (tree, const char *);
|
||||
@ -5534,7 +5535,8 @@ grokfndecl (tree ctype,
|
||||
int inlinep,
|
||||
int funcdef_flag,
|
||||
int template_count,
|
||||
tree in_namespace)
|
||||
tree in_namespace,
|
||||
tree* attrlist)
|
||||
{
|
||||
tree decl;
|
||||
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
|
||||
@ -5752,6 +5754,12 @@ grokfndecl (tree ctype,
|
||||
if (decl == error_mark_node)
|
||||
return NULL_TREE;
|
||||
|
||||
if (attrlist)
|
||||
{
|
||||
cplus_decl_attributes (&decl, *attrlist, 0);
|
||||
*attrlist = NULL_TREE;
|
||||
}
|
||||
|
||||
if (ctype != NULL_TREE
|
||||
&& (! TYPE_FOR_JAVA (ctype) || check_java_method (decl))
|
||||
&& check)
|
||||
@ -5762,7 +5770,7 @@ grokfndecl (tree ctype,
|
||||
(processing_template_decl
|
||||
> template_class_depth (ctype))
|
||||
? current_template_parms
|
||||
: NULL_TREE);
|
||||
: NULL_TREE);
|
||||
|
||||
if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
|
||||
/* Because grokfndecl is always supposed to return a
|
||||
@ -7839,7 +7847,7 @@ grokdeclarator (const cp_declarator *declarator,
|
||||
unqualified_id,
|
||||
virtualp, flags, quals, raises,
|
||||
friendp ? -1 : 0, friendp, publicp, inlinep,
|
||||
funcdef_flag, template_count, in_namespace);
|
||||
funcdef_flag, template_count, in_namespace, attrlist);
|
||||
if (decl == NULL_TREE)
|
||||
return decl;
|
||||
#if 0
|
||||
@ -7886,7 +7894,7 @@ grokdeclarator (const cp_declarator *declarator,
|
||||
unqualified_id,
|
||||
virtualp, flags, quals, raises,
|
||||
friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
|
||||
template_count, in_namespace);
|
||||
template_count, in_namespace, attrlist);
|
||||
if (decl == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
}
|
||||
@ -8070,7 +8078,7 @@ grokdeclarator (const cp_declarator *declarator,
|
||||
virtualp, flags, quals, raises,
|
||||
1, friendp,
|
||||
publicp, inlinep, funcdef_flag,
|
||||
template_count, in_namespace);
|
||||
template_count, in_namespace, attrlist);
|
||||
if (decl == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
|
||||
@ -10088,8 +10096,6 @@ start_function (cp_decl_specifier_seq *declspecs,
|
||||
if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
|
||||
return 0;
|
||||
|
||||
cplus_decl_attributes (&decl1, attrs, 0);
|
||||
|
||||
/* If #pragma weak was used, mark the decl weak now. */
|
||||
if (global_scope_p (current_binding_level))
|
||||
maybe_apply_pragma_weak (decl1);
|
||||
|
@ -7441,6 +7441,7 @@ cp_parser_conversion_type_id (cp_parser* parser)
|
||||
tree attributes;
|
||||
cp_decl_specifier_seq type_specifiers;
|
||||
cp_declarator *declarator;
|
||||
tree type_specified;
|
||||
|
||||
/* Parse the attributes. */
|
||||
attributes = cp_parser_attributes_opt (parser);
|
||||
@ -7452,8 +7453,11 @@ cp_parser_conversion_type_id (cp_parser* parser)
|
||||
/* Parse the conversion-declarator. */
|
||||
declarator = cp_parser_conversion_declarator_opt (parser);
|
||||
|
||||
return grokdeclarator (declarator, &type_specifiers, TYPENAME,
|
||||
/*initialized=*/0, &attributes);
|
||||
type_specified = grokdeclarator (declarator, &type_specifiers, TYPENAME,
|
||||
/*initialized=*/0, &attributes);
|
||||
if (attributes)
|
||||
cplus_decl_attributes (&type_specified, attributes, /*flags=*/0);
|
||||
return type_specified;
|
||||
}
|
||||
|
||||
/* Parse an (optional) conversion-declarator.
|
||||
|
36
gcc/testsuite/g++.dg/ext/attribute-test-1.C
Normal file
36
gcc/testsuite/g++.dg/ext/attribute-test-1.C
Normal file
@ -0,0 +1,36 @@
|
||||
// { dg-do run }
|
||||
// PR c++/13989
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
#define vector __attribute__((vector_size(16)))
|
||||
|
||||
struct Constants {
|
||||
inline vector unsigned int deadbeef(void) const {
|
||||
return (vector unsigned int){0xdeadbeef, 0xabababab, 0x55555555, 0x12345678};
|
||||
};
|
||||
};
|
||||
|
||||
inline vector unsigned int const_deadbeef(Constants &C)
|
||||
{
|
||||
return C.deadbeef();
|
||||
}
|
||||
|
||||
union u {
|
||||
unsigned int f[4];
|
||||
vector unsigned int v;
|
||||
} data;
|
||||
|
||||
int main()
|
||||
{
|
||||
Constants c;
|
||||
data.v = const_deadbeef(c);
|
||||
|
||||
if (data.f[0] != 0xdeadbeef || data.f[1] != 0xabababab
|
||||
|| data.f[2] != 0x55555555 || data.f[3] != 0x12345678)
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
47
gcc/testsuite/g++.dg/ext/attribute-test-2.C
Normal file
47
gcc/testsuite/g++.dg/ext/attribute-test-2.C
Normal file
@ -0,0 +1,47 @@
|
||||
// { dg-do run }
|
||||
// PR c++/9844
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
#define vector __attribute__((vector_size(16)))
|
||||
|
||||
class vector_holder
|
||||
{
|
||||
char __attribute__((vector_size(16))) vec;
|
||||
char __attribute__((vector_size(16))) vec1;
|
||||
public:
|
||||
operator __attribute__((vector_size(16))) short (void) {
|
||||
return (__attribute__((vector_size(16))) short) vec;
|
||||
}
|
||||
|
||||
operator __attribute__((vector_size(16))) int (void) {
|
||||
return (__attribute__((vector_size(16))) int) vec1;
|
||||
}
|
||||
|
||||
vector_holder () {
|
||||
vec = (__attribute__((vector_size(16))) char) {'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd',
|
||||
'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'};
|
||||
vec1 = (__attribute__((vector_size(16))) char) {'m', 'n', 'o', 'q', 'm', 'n', 'o', 'p',
|
||||
'm', 'n', 'o', 'q', 'm', 'n', 'o', 'p'};
|
||||
}
|
||||
};
|
||||
|
||||
union u {
|
||||
char f[16];
|
||||
vector unsigned int v;
|
||||
} data;
|
||||
|
||||
|
||||
vector_holder vh;
|
||||
|
||||
int main()
|
||||
{
|
||||
data.v = (__attribute__((vector_size(16))) short) vh;
|
||||
if (data.f[0] != 'a' || data.f[15] != 'd')
|
||||
abort();
|
||||
data.v = (__attribute__((vector_size(16))) int) vh;
|
||||
if (data.f[0] != 'm' || data.f[15] != 'p')
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
55
gcc/testsuite/g++.dg/ext/attribute-test-3.C
Normal file
55
gcc/testsuite/g++.dg/ext/attribute-test-3.C
Normal file
@ -0,0 +1,55 @@
|
||||
// { dg-do run }
|
||||
|
||||
#define vector __attribute__((vector_size(16)))
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
class Star
|
||||
{
|
||||
public:
|
||||
inline vector float foo() const;
|
||||
|
||||
Star()
|
||||
{
|
||||
data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0;
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
float f[4];
|
||||
vector float v;
|
||||
} data;
|
||||
|
||||
friend vector float fTest(const Star &);
|
||||
};
|
||||
|
||||
vector float Star::foo() const
|
||||
{
|
||||
return data.v;
|
||||
}
|
||||
|
||||
vector float fTest(const Star & val)
|
||||
{
|
||||
vector float vf = val.foo();
|
||||
return vf;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
Star s;
|
||||
|
||||
union u {
|
||||
float f[4];
|
||||
vector float v;
|
||||
} data;
|
||||
|
||||
data.v = fTest(s);
|
||||
for (int i=0 ; i < 4; i++)
|
||||
if (data.f[i] != (float)(i+1))
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
48
gcc/testsuite/g++.dg/ext/attribute-test-4.C
Normal file
48
gcc/testsuite/g++.dg/ext/attribute-test-4.C
Normal file
@ -0,0 +1,48 @@
|
||||
// { dg-do run }
|
||||
|
||||
#define vector __attribute__((vector_size(16)))
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
union U {
|
||||
float f[4];
|
||||
vector float v;
|
||||
} data;
|
||||
|
||||
class Star
|
||||
{
|
||||
public:
|
||||
static vector float foo();
|
||||
|
||||
Star()
|
||||
{
|
||||
data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0;
|
||||
}
|
||||
|
||||
private:
|
||||
friend vector float fTest();
|
||||
};
|
||||
|
||||
vector float Star::foo()
|
||||
{
|
||||
return data.v;
|
||||
}
|
||||
|
||||
vector float fTest()
|
||||
{
|
||||
vector float vf = Star::foo();
|
||||
return vf;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
U data;
|
||||
Star s;
|
||||
|
||||
|
||||
data.v = fTest();
|
||||
for (int i=0 ; i < 4; i++)
|
||||
if (data.f[i] != (float)(i+1))
|
||||
abort();
|
||||
return 0;
|
||||
}
|
@ -5642,10 +5642,15 @@ reconstruct_complex_type (tree type, tree bottom)
|
||||
}
|
||||
else if (TREE_CODE (type) == METHOD_TYPE)
|
||||
{
|
||||
tree argtypes;
|
||||
inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
|
||||
/* The build_method_type_directly() routine prepends 'this' to argument list,
|
||||
so we must compensate by getting rid of it. */
|
||||
argtypes = TYPE_ARG_TYPES (type);
|
||||
outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
|
||||
inner,
|
||||
TYPE_ARG_TYPES (type));
|
||||
TYPE_ARG_TYPES (outer) = argtypes;
|
||||
}
|
||||
else
|
||||
return bottom;
|
||||
|
Loading…
Reference in New Issue
Block a user