aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-12-22 18:00:39 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-12-22 18:00:39 +0000
commitdfb5c52315ecc5b6ebabf2d7cb3d3d69f35a378b (patch)
tree92d85ea737af3ab701ec3aa12c9d0ae5763ee5c1
parent606145e4e0e54d412059033a6261c53bf11d7b6d (diff)
downloadgcc-dfb5c52315ecc5b6ebabf2d7cb3d3d69f35a378b.zip
gcc-dfb5c52315ecc5b6ebabf2d7cb3d3d69f35a378b.tar.gz
gcc-dfb5c52315ecc5b6ebabf2d7cb3d3d69f35a378b.tar.bz2
re PR c++/18464 (error message about "non-lvalue in unary '&'" when using ?: operator)
PR c++/18464 * call.c (build_this): In templates, do not bother with build_unary_op. * typeck.c (unary_complex_lvalue): In a template, always refuse simplifications. PR c++/18492 * cp-gimplify.c (cp_genericize): Relax assertion. PR c++/11224 * cvt.c (convert_to_void): Warn about unused values. PR c++/18257 * rtti.c (emit_support_tinfos): On systems without weak symbols, emit the runtime library type-info objects as non-COMDAT. PR c++/18464 * g++.dg/template/cond5.C: New test. PR c++/18492 * g++.dg/inherit/thunk3.C: New test. PR c++/11224 * g++.dg/warn/Wunused-9.C: New test. From-SVN: r92491
-rw-r--r--gcc/cp/ChangeLog18
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/cp/cp-gimplify.c24
-rw-r--r--gcc/cp/cvt.c40
-rw-r--r--gcc/cp/rtti.c42
-rw-r--r--gcc/cp/typeck.c9
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/inherit/thunk3.C12
-rw-r--r--gcc/testsuite/g++.dg/template/cond5.C9
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-9.C38
10 files changed, 181 insertions, 32 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d28a020..accc1e3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,21 @@
+2004-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18464
+ * call.c (build_this): In templates, do not bother with
+ build_unary_op.
+ * typeck.c (unary_complex_lvalue): In a template, always refuse
+ simplifications.
+
+ PR c++/18492
+ * cp-gimplify.c (cp_genericize): Relax assertion.
+
+ PR c++/11224
+ * cvt.c (convert_to_void): Warn about unused values.
+
+ PR c++/18257
+ * rtti.c (emit_support_tinfos): On systems without weak symbols,
+ emit the runtime library type-info objects as non-COMDAT.
+
2004-12-21 Mark Mitchell <mark@codesourcery.com>
PR c++/18378
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 69e06e0..f94526a 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2333,10 +2333,18 @@ any_strictly_viable (struct z_candidate *cands)
return false;
}
+/* OBJ is being used in an expression like "OBJ.f (...)". In other
+ words, it is about to become the "this" pointer for a member
+ function call. Take the address of the object. */
+
static tree
build_this (tree obj)
{
- /* Fix this to work on non-lvalues. */
+ /* In a template, we are only concerned about the type of the
+ expression, so we can take a shortcut. */
+ if (processing_template_decl)
+ return build_address (obj);
+
return build_unary_op (ADDR_EXPR, obj, 0);
}
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index d953156..413a933 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -334,17 +334,19 @@ cp_genericize (tree fndecl)
/* Fix up the types of parms passed by invisible reference. */
for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
- {
- gcc_assert (!DECL_BY_REFERENCE (t));
- if (TREE_ADDRESSABLE (TREE_TYPE (t)))
- {
- gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
- TREE_TYPE (t) = DECL_ARG_TYPE (t);
- DECL_BY_REFERENCE (t) = 1;
- TREE_ADDRESSABLE (t) = 0;
- relayout_decl (t);
- }
- }
+ if (TREE_ADDRESSABLE (TREE_TYPE (t)))
+ {
+ /* If a function's arguments are copied to create a thunk,
+ then DECL_BY_REFERENCE will be set -- but the type of the
+ argument will be a pointer type, so we will never get
+ here. */
+ gcc_assert (!DECL_BY_REFERENCE (t));
+ gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
+ TREE_TYPE (t) = DECL_ARG_TYPE (t);
+ DECL_BY_REFERENCE (t) = 1;
+ TREE_ADDRESSABLE (t) = 0;
+ relayout_decl (t);
+ }
/* Do the same for the return value. */
if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 2d73ab8..64db100 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -909,9 +909,43 @@ convert_to_void (tree expr, const char *implicit)
if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
{
- if (implicit && warn_unused_value
- && !TREE_SIDE_EFFECTS (expr) && !TREE_NO_WARNING (expr))
- warning ("%s has no effect", implicit);
+ if (implicit && warn_unused_value && !TREE_NO_WARNING (expr))
+ {
+ /* The middle end does not warn about expressions that have
+ been explicitly cast to void, so we must do so here. */
+ if (!TREE_SIDE_EFFECTS (expr))
+ warning ("%s has no effect", implicit);
+ else
+ {
+ tree e;
+ enum tree_code code;
+ enum tree_code_class class;
+
+ e = expr;
+ /* We might like to warn about (say) "(int) f()", as the
+ cast has no effect, but the compiler itself will
+ generate implicit conversions under some
+ circmstances. (For example a block copy will be
+ turned into a call to "__builtin_memcpy", with a
+ conversion of the return value to an appropriate
+ type.) So, to avoid false positives, we strip
+ conversions. */
+ STRIP_NOPS (e);
+
+ code = TREE_CODE (e);
+ class = TREE_CODE_CLASS (code);
+ if (class == tcc_comparison
+ || class == tcc_unary
+ || (class == tcc_binary
+ && !(code == MODIFY_EXPR
+ || code == INIT_EXPR
+ || code == PREDECREMENT_EXPR
+ || code == PREINCREMENT_EXPR
+ || code == POSTDECREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)))
+ warning ("value computed is not used");
+ }
+ }
expr = build1 (CONVERT_EXPR, void_type_node, expr);
}
return expr;
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index c113e1c..6c92d19 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1345,22 +1345,32 @@ emit_support_tinfos (void)
for (ix = 0; fundamentals[ix]; ix++)
{
tree bltn = *fundamentals[ix];
- tree bltn_ptr = build_pointer_type (bltn);
- tree bltn_const_ptr = build_pointer_type
- (build_qualified_type (bltn, TYPE_QUAL_CONST));
- tree tinfo;
-
- tinfo = get_tinfo_decl (bltn);
- TREE_USED (tinfo) = 1;
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
-
- tinfo = get_tinfo_decl (bltn_ptr);
- TREE_USED (tinfo) = 1;
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
-
- tinfo = get_tinfo_decl (bltn_const_ptr);
- TREE_USED (tinfo) = 1;
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
+ tree types[3] = {
+ bltn,
+ build_pointer_type (bltn),
+ build_pointer_type (build_qualified_type (bltn, TYPE_QUAL_CONST))
+ };
+ int i;
+
+ for (i = 0; i < 3; ++i)
+ {
+ tree tinfo;
+ tinfo = get_tinfo_decl (types[i]);
+ TREE_USED (tinfo) = 1;
+ mark_needed (tinfo);
+ /* The C++ ABI requires that these objects be COMDAT. But,
+ On systems without weak symbols, initialized COMDAT
+ objects are emitted with internal linkage. (See
+ comdat_linkage for details.) Since we want these objects
+ to have external linkage so that copies do not have to be
+ emitted in code outside the runtime library, we make them
+ non-COMDAT here. */
+ if (!flag_weak)
+ {
+ gcc_assert (TREE_PUBLIC (tinfo) && !DECL_COMDAT (tinfo));
+ DECL_INTERFACE_KNOWN (tinfo) = 1;
+ }
+ }
}
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 778e331..6ce3811 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4153,11 +4153,18 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
for certain kinds of expressions which are not really lvalues
but which we can accept as lvalues.
- If ARG is not a kind of expression we can handle, return zero. */
+ If ARG is not a kind of expression we can handle, return
+ NULL_TREE. */
tree
unary_complex_lvalue (enum tree_code code, tree arg)
{
+ /* Inside a template, making these kinds of adjustments is
+ pointless; we are only concerned with the type of the
+ expression. */
+ if (processing_template_decl)
+ return NULL_TREE;
+
/* Handle (a, b) used as an "lvalue". */
if (TREE_CODE (arg) == COMPOUND_EXPR)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5f0074a..555353a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2004-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18464
+ * g++.dg/template/cond5.C: New test.
+
+ PR c++/18492
+ * g++.dg/inherit/thunk3.C: New test.
+
+ PR c++/11224
+ * g++.dg/warn/Wunused-9.C: New test.
+
2004-12-22 Janis Johnson <janis187@us.ibm.com>
* lib/gcc-dg.exp (dg-xfail-if): Fix the flags compared against.
diff --git a/gcc/testsuite/g++.dg/inherit/thunk3.C b/gcc/testsuite/g++.dg/inherit/thunk3.C
new file mode 100644
index 0000000..9787aa9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/thunk3.C
@@ -0,0 +1,12 @@
+// PR c++/18492
+
+struct X{ ~X(); };
+struct B
+{
+ virtual void a( X ) = 0;
+};
+struct D : public virtual B
+{
+ void a( X );
+};
+void D::a( X ){}
diff --git a/gcc/testsuite/g++.dg/template/cond5.C b/gcc/testsuite/g++.dg/template/cond5.C
new file mode 100644
index 0000000..bba31e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/cond5.C
@@ -0,0 +1,9 @@
+// PR c++/18464
+
+struct A
+{
+ A(int);
+ operator void*() const;
+};
+
+template<int> void foo(const A& x) { 0 ? x : (x ? x : 0); }
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-9.C b/gcc/testsuite/g++.dg/warn/Wunused-9.C
new file mode 100644
index 0000000..30e3f6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-9.C
@@ -0,0 +1,38 @@
+// PR c++/11224
+// { dg-options "-Wunused" }
+
+struct someclass {
+
+ bool isEmpty() const { return true; }
+};
+
+int main()
+{
+ bool bOk = false;
+ someclass foo;
+
+ bOk == foo.isEmpty(); // { dg-warning "not used" }
+
+ return bOk;
+}
+
+int& f();
+
+void g() {
+ f() == 0; // { dg-warning "not used" }
+ f() != 1; // { dg-warning "not used" }
+ f() < 2; // { dg-warning "not used" }
+ f() > 3; // { dg-warning "not used" }
+ f() <= 4; // { dg-warning "not used" }
+ f() >= 5; // { dg-warning "not used" }
+ f() + 6; // { dg-warning "not used" }
+ f() - 7; // { dg-warning "not used" }
+ f() * 8; // { dg-warning "not used" }
+ f() / 9; // { dg-warning "not used" }
+ +f(); // { dg-warning "not used" "" { xfail *-*-* } }
+ -f(); // { dg-warning "not used" }
+ ++f();
+ --f();
+ f() = 10;
+ f() <<= 11;
+}