PR c++/9844, PR c++/13989

PR c++/9844, PR c++/13989
Reviewed by Mark Mitchel.

From-SVN: r87971
This commit is contained in:
Fariborz Jahanian 2004-09-23 18:22:25 +00:00 committed by Fariborz Jahanian
parent 093942ac67
commit 037cc9c5dc
10 changed files with 241 additions and 12 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)))

View File

@ -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);

View File

@ -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.

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View File

@ -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;