Commit 2e1df0f0 by Diego Novillo

cp-tree.h (LOOKUP_EXPLICIT_TMPL_ARGS): Define.

cp/ChangeLog
2011-04-29  Le-Chun Wu  <lcwu@google.com>

	* cp-tree.h (LOOKUP_EXPLICIT_TMPL_ARGS): Define.
	* call.c (build_new_function_call): Set it for TEMPLATE_ID_EXPRs.
	(build_over_call): Use it to determine whether to emit a NULL
	warning for template function instantiations.
	(build_new_method_call): Set LOOKUP_EXPLICIT_TMPL_ARGS if
	EXPLICIT_TARGS is set.

2011-04-29  Diego Novillo  <dnovillo@google.com>
	    Le-Chun Wu  <lcwu@google.com>

	* call.c (conversion_null_warnings): Also handle assignments
	when warning about NULL conversions.

testsuite/ChangeLog
2011-04-29  Le-Chun Wu  <lcwu@google.com>

	* g++.dg/warn/Wnull-conversion-1.C: New.
	* g++.dg/warn/Wnull-conversion-2.C: New.

2011-04-29  Le-Chun Wu  <lcwu@google.com>

	* g++.dg/warn/Wconversion-null-2.C: Do not expect a NULL
	  warning in implicitly instantiated templates.

2011-04-29  Diego Novillo  <dnovillo@google.com>

	* g++.old-deja/g++.other/null3.C: Expect warning about converting
	boolean to a pointer.

From-SVN: r173217
parent 9a4ac625
......@@ -4,6 +4,21 @@
* init.c (perform_member_init): Check build_value_init return
value for error_mark_node.
2011-04-29 Diego Novillo <dnovillo@google.com>
Le-Chun Wu <lcwu@google.com>
* call.c (conversion_null_warnings): Also handle assignments
when warning about NULL conversions.
2011-04-29 Le-Chun Wu <lcwu@google.com>
* cp-tree.h (LOOKUP_EXPLICIT_TMPL_ARGS): Define.
* call.c (build_new_function_call): Set it for TEMPLATE_ID_EXPRs.
(build_over_call): Use it to determine whether to emit a NULL
warning for template function instantiations.
(build_new_method_call): Set LOOKUP_EXPLICIT_TMPL_ARGS if
EXPLICIT_TARGS is set.
2011-04-29 Nicola Pero <nicola.pero@meta-innovation.com>,
Mike Stump <mikestump@comcast.net>
......
......@@ -3734,7 +3734,16 @@ build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p,
result = error_mark_node;
}
else
result = build_over_call (cand, LOOKUP_NORMAL, complain);
{
int flags = LOOKUP_NORMAL;
/* If fn is template_id_expr, the call has explicit template arguments
(e.g. func<int>(5)), communicate this info to build_over_call
through flags so that later we can use it to decide whether to warn
about peculiar null pointer conversion. */
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
result = build_over_call (cand, flags, complain);
}
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
......@@ -5369,10 +5378,16 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
}
/* Issue warnings if "false" is converted to a NULL pointer */
else if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
else if (expr == boolean_false_node && POINTER_TYPE_P (t))
{
if (fn)
warning_at (input_location, OPT_Wconversion_null,
"converting %<false%> to pointer type for argument %P of %qD",
argnum, fn);
"converting %<false%> to pointer type for argument %P "
"of %qD", argnum, fn);
else
warning_at (input_location, OPT_Wconversion_null,
"converting %<false%> to pointer type %qT", t);
}
}
/* Perform the conversions in CONVS on the expression EXPR. FN and
......@@ -6293,9 +6308,36 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
tree type = TREE_VALUE (parm);
tree arg = VEC_index (tree, args, arg_index);
bool conversion_warning = true;
conv = convs[i];
/* If the argument is NULL and used to (implicitly) instantiate a
template function (and bind one of the template arguments to
the type of 'long int'), we don't want to warn about passing NULL
to non-pointer argument.
For example, if we have this template function:
template<typename T> void func(T x) {}
we want to warn (when -Wconversion is enabled) in this case:
void foo() {
func<int>(NULL);
}
but not in this case:
void foo() {
func(NULL);
}
*/
if (arg == null_node
&& DECL_TEMPLATE_INFO (fn)
&& cand->template_decl
&& !(flags & LOOKUP_EXPLICIT_TMPL_ARGS))
conversion_warning = false;
/* Warn about initializer_list deduction that isn't currently in the
working draft. */
if (cxx_dialect > cxx98
......@@ -6326,7 +6368,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
}
}
val = convert_like_with_context (conv, arg, fn, i-is_method, complain);
val = convert_like_with_context (conv, arg, fn, i-is_method,
conversion_warning
? complain
: complain & (~tf_warning));
val = convert_for_arg_passing (type, val);
if (val == error_mark_node)
......@@ -7061,6 +7106,8 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL)
&& resolves_to_fixed_type_p (instance, 0))
flags |= LOOKUP_NONVIRTUAL;
if (explicit_targs)
flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
/* Now we know what function is being called. */
if (fn_p)
*fn_p = fn;
......
......@@ -4242,6 +4242,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
/* Used in calls to store_init_value to suppress its usual call to
digest_init. */
#define LOOKUP_ALREADY_DIGESTED (LOOKUP_DEFAULTED << 1)
/* An instantiation with explicit template arguments. */
#define LOOKUP_EXPLICIT_TMPL_ARGS (LOOKUP_ALREADY_DIGESTED << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
......
......@@ -17,6 +17,21 @@
PR c++/48606
* g++.dg/init/ctor10.C: New.
2011-04-29 Le-Chun Wu <lcwu@google.com>
* g++.dg/warn/Wconversion-null-2.C: Do not expect a NULL
warning in implicitly instantiated templates.
2011-04-29 Le-Chun Wu <lcwu@google.com>
* g++.dg/warn/Wnull-conversion-1.C: New.
* g++.dg/warn/Wnull-conversion-2.C: New.
2011-04-29 Diego Novillo <dnovillo@google.com>
* g++.old-deja/g++.other/null3.C: Expect warning about
converting boolean to a pointer.
2011-04-29 Paul Thomas <pault@gcc.gnu.org>
PR fortran/48462
......
......@@ -44,6 +44,6 @@ int main()
k(NULL); // { dg-warning "" } converting NULL to int
g(NULL); // { dg-warning "" } converting NULL to int
h<NULL>(); // No warning: NULL bound to integer template parameter
l(NULL); // { dg-warning "" } converting NULL to int
l(NULL); // No warning: NULL is used to implicitly instantiate the template
NULL && NULL; // No warning: converting NULL to bool is OK
}
// { dg-do compile }
// { dg-options "-Wconversion-null" }
#include <stddef.h>
void func1(int* ptr);
void func2() {
int* t = false; // { dg-warning "converting 'false' to pointer" }
int* p;
p = false; // { dg-warning "converting 'false' to pointer" }
int* r = sizeof(char) / 2;
func1(false); // { dg-warning "converting 'false' to pointer" }
int i = NULL; // { dg-warning "converting to non-pointer" }
}
// { dg-do compile }
// { dg-options "-Wconversion-null" }
#include <stddef.h>
class Foo {
public:
template <typename T1, typename T2>
static void Compare(const T1& expected, const T2& actual) { }
template <typename T1, typename T2>
static void Compare(const T1& expected, T2* actual) { }
};
template<typename T1>
class Foo2 {
public:
Foo2(int x);
template<typename T2> void Bar(T2 y);
};
template<typename T3> void func(T3 x) { }
typedef Foo2<int> MyFooType;
void func1(long int a) {
MyFooType *foo2 = new MyFooType(NULL); // { dg-warning "passing NULL to" }
foo2->Bar(a);
func(NULL);
func<int>(NULL); // { dg-warning "passing NULL to" }
func<int *>(NULL);
}
int x = 1;
main()
{
int *p = &x;
Foo::Compare(0, *p);
Foo::Compare<long int, int>(NULL, p); // { dg-warning "passing NULL to" }
Foo::Compare(NULL, p);
func1(NULL); // { dg-warning "passing NULL to" }
}
......@@ -2,5 +2,5 @@
void x()
{
int* p = 1==0;
int* p = 1==0; // { dg-warning "converting 'false' to pointer" }
}
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