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
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();
--- /dev/null
+/*$ -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;
+}
#include "warning.h"
warning_t warning = {
+ .aggregate_return = false,
.attribute = true,
.char_subscripts = true,
.declaration_after_statement = false,
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);
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. */