summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mmitchel@gcc.gnu.org>2004-05-31 21:24:31 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-05-31 21:24:31 +0000
commitc8b2e872a83dd3869ffc4443201a1f3096bc3a6c (patch)
tree5e0812c5ac7d5a81ea49d40fed31c165f91fb9df /gcc/cp
parent7c9fee34e5688d79d96db0e2b2e56d7273cb4335 (diff)
downloadgcc-c8b2e872a83dd3869ffc4443201a1f3096bc3a6c.tar.gz
re PR c++/15742 ('noreturn' attribute ignored in method of template functions.)
PR c++/15742 * call.c (build_over_call): Set current_function_returns_abnormally even in template functions. PR c++/15696 * cp-tree.h (invalid_nonstatic_memfn_p): New function. * cvt.c (convert_to_void): Use it. * typeck.c (invalid_nonstatic_memfn_p): New function. (decay_conversion): Use it. PR c++/15625 * pt.c (tsubst_decl): Set DECL_FRIEND_CONTEXT for instantiated templates. PR c++/15629 * name-lookup.c (arg_assoc_class): Do not find template specializations. PR c++/15209 * tree.c (lvalue_p_1): Only consider the right-hand side of "." expressions when determining whether or not an express is packed. PR c++/15742 * g++.dg/warn/Wreturn-1.C: New test. PR c++/15696 * g++.dg/expr/ptrmem5.C: New test. PR c++/15625 * g++.dg/template/friend27.C: New test. PR c++/15629 * g++.dg/template/friend28.C: New test. * g++.dg/template/friend.C: Do not depend on <iostream>. Add error message. PR c++/15209 * g++.dg/ext/packed3.C: Remove bogus error. * g++.dg/ext/packed4.C: Remove bogus check. * g++.dg/ext/packed6.C: New test. From-SVN: r82499
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/cvt.c2
-rw-r--r--gcc/cp/name-lookup.c18
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/cp/tree.c4
-rw-r--r--gcc/cp/typeck.c34
7 files changed, 57 insertions, 9 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index d65f0eeb23a..ecace2dd78e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4561,6 +4561,8 @@ build_over_call (struct z_candidate *cand, int flags)
tree return_type;
return_type = TREE_TYPE (TREE_TYPE (fn));
expr = build (CALL_EXPR, return_type, fn, args, NULL_TREE);
+ if (TREE_THIS_VOLATILE (fn) && cfun)
+ current_function_returns_abnormally = 1;
if (!VOID_TYPE_P (return_type))
require_complete_type (return_type);
return convert_from_reference (expr);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8b4e7f7af15..086090c0d22 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4244,6 +4244,7 @@ extern tree build_address (tree);
extern tree build_nop (tree, tree);
extern tree non_reference (tree);
extern tree lookup_anon_field (tree, tree);
+extern bool invalid_nonstatic_memfn_p (tree);
/* in typeck2.c */
extern void require_complete_eh_spec_types (tree, tree);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index b22948106b2..61e179ed1b6 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -784,6 +784,8 @@ convert_to_void (tree expr, const char *implicit)
return error_mark_node;
if (!TREE_TYPE (expr))
return expr;
+ if (invalid_nonstatic_memfn_p (expr))
+ return error_mark_node;
if (VOID_TYPE_P (TREE_TYPE (expr)))
return expr;
switch (TREE_CODE (expr))
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 195070a8033..238023da877 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4306,11 +4306,21 @@ arg_assoc_class (struct arg_lookup *k, tree type)
if (k->name == FRIEND_NAME (list))
for (friends = FRIEND_DECLS (list); friends;
friends = TREE_CHAIN (friends))
- /* Only interested in global functions with potentially hidden
- (i.e. unqualified) declarations. */
- if (CP_DECL_CONTEXT (TREE_VALUE (friends)) == context)
- if (add_function (k, TREE_VALUE (friends)))
+ {
+ tree fn = TREE_VALUE (friends);
+
+ /* Only interested in global functions with potentially hidden
+ (i.e. unqualified) declarations. */
+ if (CP_DECL_CONTEXT (fn) != context)
+ continue;
+ /* Template specializations are never found by name lookup.
+ (Templates themselves can be found, but not template
+ specializations.) */
+ if (TREE_CODE (fn) == FUNCTION_DECL && DECL_USE_TEMPLATE (fn))
+ continue;
+ if (add_function (k, fn))
return true;
+ }
/* Process template arguments. */
if (CLASSTYPE_TEMPLATE_INFO (type)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 09f1e9263f5..cbe4bd9b070 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6273,6 +6273,11 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
grok_op_properties (r, DECL_FRIEND_P (r),
(complain & tf_error) != 0);
+
+ if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
+ SET_DECL_FRIEND_CONTEXT (r,
+ tsubst (DECL_FRIEND_CONTEXT (t),
+ args, complain, in_decl));
}
break;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index e9bfdb8be9a..365e0753074 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -90,6 +90,10 @@ lvalue_p_1 (tree ref,
case COMPONENT_REF:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues);
+ /* In an expression of the form "X.Y", the packed-ness of the
+ expression does not depend on "X". */
+ op1_lvalue_kind &= ~clk_packed;
+ /* Look at the member designator. */
if (!op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index b8e48b420d8..5e5dcc4a2ae 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1292,6 +1292,33 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
}
+/* EXPR is being used in a context that is not a function call.
+ Enforce:
+
+ [expr.ref]
+
+ The expression can be used only as the left-hand operand of a
+ member function call.
+
+ [expr.mptr.operator]
+
+ If the result of .* or ->* is a function, then that result can be
+ used only as the operand for the function call operator ().
+
+ by issuing an error message if appropriate. Returns true iff EXPR
+ violates these rules. */
+
+bool
+invalid_nonstatic_memfn_p (tree expr)
+{
+ if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
+ {
+ error ("invalid use of non-static member function");
+ return true;
+ }
+ return false;
+}
+
/* Perform the conversions in [expr] that apply when an lvalue appears
in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
function-to-pointer conversions.
@@ -1344,11 +1371,8 @@ decay_conversion (tree exp)
error ("void value not ignored as it ought to be");
return error_mark_node;
}
- if (code == METHOD_TYPE)
- {
- error ("invalid use of non-static member function");
- return error_mark_node;
- }
+ if (invalid_nonstatic_memfn_p (exp))
+ return error_mark_node;
if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
return build_unary_op (ADDR_EXPR, exp, 0);
if (code == ARRAY_TYPE)