+2014-04-16 Patrick Palka <patrick@parcs.ath.cx>
+
+ PR c++/60765
+ * decl2.c (cplus_decl_attributes): Handle
+ pointer-to-member-function declarations.
+
+2014-04-16 Patrick Palka <patrick@parcs.ath.cx>
+
+ PR c++/60764
+ * call.c (build_user_type_coversion): Use build_dummy_object
+ to create the placeholder object for a constructor method call.
+ (build_special_member_call): Likewise.
+ (build_over_call): Check for the placeholder object with
+ is_dummy_object.
+ (build_new_method_call_1): Likewise. Don't attempt to resolve
+ a dummy object for a constructor method call.
+
2014-04-16 Paul Pluzhnikov <ppluzhnikov@google.com>
PR c++/59295
{
int ctorflags = flags;
- first_arg = build_int_cst (build_pointer_type (totype), 0);
- first_arg = build_fold_indirect_ref (first_arg);
+ first_arg = build_dummy_object (totype);
/* We should never try to call the abstract or base constructor
from here. */
ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
temp or an INIT_EXPR otherwise. */
fa = argarray[0];
- if (integer_zerop (fa))
+ if (is_dummy_object (fa))
{
if (TREE_CODE (arg) == TARGET_EXPR)
return arg;
/* Handle the special case where INSTANCE is NULL_TREE. */
if (name == complete_ctor_identifier && !instance)
- {
- instance = build_int_cst (build_pointer_type (class_type), 0);
- instance = build1 (INDIRECT_REF, class_type, instance);
- }
+ instance = build_dummy_object (class_type);
else
{
if (name == complete_dtor_identifier
if (init)
{
- if (INDIRECT_REF_P (instance)
- && integer_zerop (TREE_OPERAND (instance, 0)))
+ if (is_dummy_object (instance))
return get_target_expr_sfinae (init, complain);
init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
TREE_SIDE_EFFECTS (init) = true;
}
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
+ && !DECL_CONSTRUCTOR_P (fn)
&& is_dummy_object (instance))
{
instance = maybe_resolve_dummy (instance);
if (TREE_CODE (*decl) == TEMPLATE_DECL)
decl = &DECL_TEMPLATE_RESULT (*decl);
- decl_attributes (decl, attributes, flags);
+ if (TREE_TYPE (*decl) && TYPE_PTRMEMFUNC_P (TREE_TYPE (*decl)))
+ {
+ attributes
+ = decl_attributes (decl, attributes, flags | ATTR_FLAG_FUNCTION_NEXT);
+ decl_attributes (&TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (*decl)),
+ attributes, flags);
+ }
+ else
+ decl_attributes (decl, attributes, flags);
if (TREE_CODE (*decl) == TYPE_DECL)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
typedef int (*F2 [[gnu::warn_unused_result]]) (int);
-typedef int (S::*F3 [[gnu::warn_unused_result]]) (int); // { dg-warning "only applies to function types" }
+typedef int (S::*F3 [[gnu::warn_unused_result]]) (int);
typedef int [[gnu::warn_unused_result]] (*F5) (int); // { dg-warning "ignored" }
--- /dev/null
+// PR c++/60765
+// { dg-options "-Wall -Wunused-parameter" }
+
+struct foo
+{
+} x;
+
+void (foo::*g) (int *) __attribute__ ((nonnull (2)));
+
+void
+fun1 (void (foo::*f) (int *) __attribute__ ((nonnull (2))))
+{
+ (x.*f) ((int *) 0); // { dg-warning "null argument" }
+}
+
+void
+fun2 (void (foo::*f) () __attribute__ ((nonnull, unused))) // { dg-bogus "unused" }
+{
+ (x.*g) ((int *) 0); // { dg-warning "null argument" }
+}
--- /dev/null
+// PR c++/60764
+// { dg-options "-Wall" }
+
+struct foo
+{
+ foo () __attribute__ ((nonnull (1)));
+};
+
+const foo &x = foo (); // { dg-bogus "null argument" }
+foo y = foo (); // { dg-bogus "null argument" }