/* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
#include "target.h"
#include "convert.h"
#include "c-common.h"
+#include "params.h"
static tree pfn_from_ptrmemfunc (tree);
static tree convert_for_assignment (tree, tree, const char *, tree, int);
return true;
}
-/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
- is a bitwise-or of the COMPARE_* flags. */
+/* Subroutine in comptypes. */
-bool
-comptypes (tree t1, tree t2, int strict)
+static bool
+structural_comptypes (tree t1, tree t2, int strict)
{
if (t1 == t2)
return true;
return targetm.comp_type_attributes (t1, t2);
}
+/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
+ is a bitwise-or of the COMPARE_* flags. */
+
+bool
+comptypes (tree t1, tree t2, int strict)
+{
+ if (strict == COMPARE_STRICT)
+ {
+ bool result;
+
+ if (t1 == t2)
+ return true;
+
+ if (t1 == error_mark_node || t2 == error_mark_node)
+ return false;
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2))
+ /* At least one of the types requires structural equality, so
+ perform a deep check. */
+ return structural_comptypes (t1, t2, strict);
+
+ if (VERIFY_CANONICAL_TYPES)
+ {
+ result = structural_comptypes (t1, t2, strict);
+
+ if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
+ {
+ /* The two types are structurally equivalent, but their
+ canonical types were different. This is a failure of the
+ canonical type propagation code.*/
+ warning(0,
+ "canonical types differ for identical types %T and %T",
+ t1, t2);
+ debug_tree (t1);
+ debug_tree (t2);
+ }
+ else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
+ {
+ /* Two types are structurally different, but the canonical
+ types are the same. This means we were over-eager in
+ assigning canonical types. */
+ warning (0,
+ "same canonical type node for different types %T and %T",
+ t1, t2);
+ debug_tree (t1);
+ debug_tree (t2);
+ }
+
+ return result;
+ }
+ else
+ return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
+ }
+ else if (strict == COMPARE_STRUCTURAL)
+ return structural_comptypes (t1, t2, COMPARE_STRICT);
+ else
+ return structural_comptypes (t1, t2, strict);
+}
+
/* Returns 1 if TYPE1 is at least as qualified as TYPE2. */
bool
"comparison");
else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0))
&& null_ptr_cst_p (op1))
- result_type = type0;
+ {
+ if (TREE_CODE (op0) == ADDR_EXPR
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
+ warning (OPT_Walways_true, "the address of %qD will never be NULL",
+ TREE_OPERAND (op0, 0));
+ result_type = type0;
+ }
else if ((code1 == POINTER_TYPE || TYPE_PTRMEM_P (type1))
&& null_ptr_cst_p (op0))
- result_type = type1;
+ {
+ if (TREE_CODE (op1) == ADDR_EXPR
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
+ warning (OPT_Walways_true, "the address of %qD will never be NULL",
+ TREE_OPERAND (op1, 0));
+ result_type = type1;
+ }
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
result = fold_if_not_in_template (result);
if (final_type != 0)
result = cp_convert (final_type, result);
+
+ if (TREE_OVERFLOW_P (result)
+ && !TREE_OVERFLOW_P (op0)
+ && !TREE_OVERFLOW_P (op1))
+ overflow_warning (result);
+
return result;
}
\f
errtype);
}
+ /* If -Wparentheses, warn about a = b = c when a has type bool. */
+ if (warn_parentheses
+ && type == boolean_type_node
+ && TREE_CODE (rhs) == MODIFY_EXPR
+ && !TREE_NO_WARNING (rhs))
+ {
+ warning (OPT_Wparentheses,
+ "suggest parentheses around assignment used as truth value");
+ TREE_NO_WARNING (rhs) = 1;
+ }
+
return perform_implicit_conversion (strip_top_quals (type), rhs);
}