-Waggregate-return implemented
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 12 Sep 2008 01:36:36 +0000 (01:36 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 12 Sep 2008 01:36:36 +0000 (01:36 +0000)
[r21871]

parser.c
parsetest/should_warn/struct_ret.c [new file with mode: 0644]
warning.c
warning.h

index ff2db11..3b8dcdf 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -5223,6 +5223,13 @@ static void parse_external_declaration(void)
                return;
        }
 
+       if (warning.aggregate_return) {
+               const type_t *return_type = type->function.return_type;
+               if (is_type_compound(return_type))
+                       warningf(HERE, "function '%Y' returns an aggregate",
+                                ndeclaration->symbol);
+       }
+
        /* ยง 6.7.5.3 (14) a function definition with () means no
         * parameters (and not unspecified parameters) */
        if (type->function.unspecified_parameters
@@ -6825,6 +6832,12 @@ static expression_t *parse_call_expression(unsigned precedence,
 
        check_format(&result->call);
 
+       if (warning.aggregate_return) {
+               const type_t *return_type = function_type->return_type;
+               if (is_type_compound(return_type))
+                       warningf(&result->base.source_position, "function call has aggregate value");
+       }
+
        return result;
 end_error:
        return create_invalid_expression();
diff --git a/parsetest/should_warn/struct_ret.c b/parsetest/should_warn/struct_ret.c
new file mode 100644 (file)
index 0000000..80fac77
--- /dev/null
@@ -0,0 +1,23 @@
+/*$ -Waggregate-return $*/
+
+struct S { int a, b; };
+union U { int a, b; };
+
+struct S testS(void) {
+       struct S ret = { 1, 2 };
+
+       return ret;
+}
+
+union U testU(void) {
+       union U ret = { 2 };
+
+       return ret;
+}
+
+int main(int argc, char *argv[]) {
+       struct S x = testS();
+       union U y = testU();
+
+       return 0;
+}
index 623ab2c..2519bf3 100644 (file)
--- a/warning.c
+++ b/warning.c
@@ -22,6 +22,7 @@
 #include "warning.h"
 
 warning_t warning = {
+       .aggregate_return              = false,
        .attribute                     = true,
        .char_subscripts               = true,
        .declaration_after_statement   = false,
@@ -101,6 +102,7 @@ void set_warning_opt(const char *const opt)
                SET(unused_value);
                SET(unused_variable);
        }
+       OPT("aggregate-return",              aggregate_return);
        OPT("attribute",                     attribute);
        OPT("char-subscripts",               char_subscripts);
        OPT("declaration-after-statement",   declaration_after_statement);
index e15b776..e141ed8 100644 (file)
--- a/warning.h
+++ b/warning.h
@@ -25,8 +25,8 @@
 void set_warning_opt(const char *opt);
 
 typedef struct warning_t {
-#if 0 // TODO
        bool aggregate_return:1;              /**< Warn if any functions that return structures or unions are defined or called */
+#if 0 // TODO
        bool bad_function_cast:1;             /**< Warn whenever a function call is cast to a non-matching type */
 #endif
        bool attribute:1;                     /**< Warn if an unexpected `__attribute__' is used or function attributes applied to variables, etc. */