From 9659d177fcd30bd65dc88ee111e3ad5f55ff45f0 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 4 Jan 2021 12:30:58 +0000 Subject: [PATCH 1/3] Avoid duplicate "warning:" or "error:" prefixes in the C/C++ front-end The gcc and cl message handlers already take care of this, and we had a mix of some messages including the "warning:" or "error:" prefix when others don't. --- .../ansi-c/linking_conflicts1/test.desc | 4 +-- .../ansi-c/linking_conflicts2/test.desc | 2 +- regression/cbmc/incomplete-structs/test.desc | 4 +-- src/ansi-c/c_typecheck_base.cpp | 7 ++-- src/ansi-c/c_typecheck_code.cpp | 8 ----- src/ansi-c/c_typecheck_expr.cpp | 2 +- src/ansi-c/c_typecheck_typecast.cpp | 2 +- src/cpp/cpp_declarator_converter.cpp | 3 +- src/cpp/cpp_typecheck_bases.cpp | 2 +- src/cpp/cpp_typecheck_code.cpp | 8 ++--- src/cpp/cpp_typecheck_compound_type.cpp | 12 +++---- src/cpp/cpp_typecheck_enum_type.cpp | 3 +- src/cpp/cpp_typecheck_expr.cpp | 36 +++++++++---------- src/cpp/cpp_typecheck_resolve.cpp | 9 +++-- src/cpp/cpp_typecheck_type.cpp | 2 +- src/goto-programs/builtin_functions.cpp | 6 ++-- src/linking/linking.cpp | 10 +++--- 17 files changed, 52 insertions(+), 68 deletions(-) diff --git a/regression/ansi-c/linking_conflicts1/test.desc b/regression/ansi-c/linking_conflicts1/test.desc index fb6ea7a2909..6ce793a9f67 100644 --- a/regression/ansi-c/linking_conflicts1/test.desc +++ b/regression/ansi-c/linking_conflicts1/test.desc @@ -3,7 +3,7 @@ main.c other.c ^EXIT=(64|1)$ ^SIGNAL=0$ -error: conflicting function declarations 'bar' -error: conflicting function declarations 'bar2' +^\S+\.c(:\d+:\d+|\(\d+\)): error: conflicting function declarations 'bar'$ +^\S+\.c(:\d+:\d+|\(\d+\)): error: conflicting function declarations 'bar2'$ -- ^warning: ignoring diff --git a/regression/ansi-c/linking_conflicts2/test.desc b/regression/ansi-c/linking_conflicts2/test.desc index f579050c99b..aa958cb6476 100644 --- a/regression/ansi-c/linking_conflicts2/test.desc +++ b/regression/ansi-c/linking_conflicts2/test.desc @@ -3,6 +3,6 @@ main.c other.c ^EXIT=(64|1)$ ^SIGNAL=0$ -error: conflicting function declarations 'foo' +^\S+\.c(:\d+:\d+|\(\d+\)): error: conflicting function declarations 'foo'$ -- ^warning: ignoring diff --git a/regression/cbmc/incomplete-structs/test.desc b/regression/cbmc/incomplete-structs/test.desc index f78df39a678..2ca3e235fa7 100644 --- a/regression/cbmc/incomplete-structs/test.desc +++ b/regression/cbmc/incomplete-structs/test.desc @@ -1,8 +1,8 @@ CORE typesmain.c types1.c types2.c types3.c -warning: pointer parameter types differ between declaration and definition "bar" -warning: pointer parameter types differ between declaration and definition "foo" +^file \S+\.c line \d+: pointer parameter types differ between declaration and definition 'bar'$ +^file \S+\.c line \d+: pointer parameter types differ between declaration and definition 'foo'$ ^VERIFICATION SUCCESSFUL$ ^EXIT=0$ ^SIGNAL=0$ diff --git a/src/ansi-c/c_typecheck_base.cpp b/src/ansi-c/c_typecheck_base.cpp index 54d36ae96fa..dd196b45260 100644 --- a/src/ansi-c/c_typecheck_base.cpp +++ b/src/ansi-c/c_typecheck_base.cpp @@ -375,7 +375,7 @@ void c_typecheck_baset::typecheck_redefinition_non_type( if(final_old.id()!=ID_code) { error().source_location=new_symbol.location; - error() << "error: function symbol '" << new_symbol.display_name() + error() << "function symbol '" << new_symbol.display_name() << "' redefined with a different type:\n" << "Original: " << to_string(old_symbol.type) << "\n" << " New: " << to_string(new_symbol.type) << eom; @@ -679,9 +679,8 @@ void c_typecheck_baset::apply_asm_label( if(asm_label_map[orig_name]!=asm_label) { error().source_location=symbol.location; - error() << "error: replacing asm renaming " - << asm_label_map[orig_name] << " by " - << asm_label << eom; + error() << "replacing asm renaming " << asm_label_map[orig_name] + << " by " << asm_label << eom; throw 0; } } diff --git a/src/ansi-c/c_typecheck_code.cpp b/src/ansi-c/c_typecheck_code.cpp index 184e1657671..1022f78abb0 100644 --- a/src/ansi-c/c_typecheck_code.cpp +++ b/src/ansi-c/c_typecheck_code.cpp @@ -629,14 +629,6 @@ void c_typecheck_baset::typecheck_ifthenelse(code_ifthenelset &code) typecheck_expr(cond); - #if 0 - if(cond.id()==ID_sideeffect && - cond.get(ID_statement)==ID_assign) - { - warning("warning: assignment in if condition"); - } - #endif - implicit_typecast_bool(cond); if(code.then_case().get_statement() == ID_decl_block) diff --git a/src/ansi-c/c_typecheck_expr.cpp b/src/ansi-c/c_typecheck_expr.cpp index 3683df91c16..d16b75036a9 100644 --- a/src/ansi-c/c_typecheck_expr.cpp +++ b/src/ansi-c/c_typecheck_expr.cpp @@ -1883,7 +1883,7 @@ void c_typecheck_baset::typecheck_expr_side_effect(side_effect_exprt &expr) if(type0.get_bool(ID_C_constant)) { error().source_location = op0.source_location(); - error() << "error: '" << to_string(op0) << "' is constant" << eom; + error() << "'" << to_string(op0) << "' is constant" << eom; throw 0; } diff --git a/src/ansi-c/c_typecheck_typecast.cpp b/src/ansi-c/c_typecheck_typecast.cpp index d0daeeec15e..b66cd72f579 100644 --- a/src/ansi-c/c_typecheck_typecast.cpp +++ b/src/ansi-c/c_typecheck_typecast.cpp @@ -34,7 +34,7 @@ void c_typecheck_baset::implicit_typecast( for(const auto &tc_warning : c_typecast.warnings) { warning().source_location=expr.find_source_location(); - warning() << "warning: conversion from '" << to_string(src_type) << "' to '" + warning() << "conversion from '" << to_string(src_type) << "' to '" << to_string(dest_type) << "': " << tc_warning << eom; } } diff --git a/src/cpp/cpp_declarator_converter.cpp b/src/cpp/cpp_declarator_converter.cpp index 558a9904289..acadd5f15a7 100644 --- a/src/cpp/cpp_declarator_converter.cpp +++ b/src/cpp/cpp_declarator_converter.cpp @@ -176,8 +176,7 @@ symbolt &cpp_declarator_convertert::convert( if(symbol_expr.id() != ID_type) { cpp_typecheck.error().source_location=name.source_location(); - cpp_typecheck.error() << "error: expected type" - << messaget::eom; + cpp_typecheck.error() << "expected type" << messaget::eom; throw 0; } diff --git a/src/cpp/cpp_typecheck_bases.cpp b/src/cpp/cpp_typecheck_bases.cpp index 7eb3b9c7601..0cc1f7e57ec 100644 --- a/src/cpp/cpp_typecheck_bases.cpp +++ b/src/cpp/cpp_typecheck_bases.cpp @@ -132,7 +132,7 @@ void cpp_typecheckt::add_base_components( if(bases.find(from_name)!=bases.end()) { error().source_location=to.source_location(); - error() << "error: non-virtual base class " << from_name + error() << "non-virtual base class " << from_name << " inherited multiple times" << eom; throw 0; } diff --git a/src/cpp/cpp_typecheck_code.cpp b/src/cpp/cpp_typecheck_code.cpp index b43e8c966b1..f9f8ea03ddb 100644 --- a/src/cpp/cpp_typecheck_code.cpp +++ b/src/cpp/cpp_typecheck_code.cpp @@ -278,10 +278,10 @@ void cpp_typecheckt::typecheck_member_initializer(codet &code) if(access == ID_private || access == ID_noaccess) { #if 0 - error().source_location=code.source_location()); - str << "error: constructor of '" - << to_string(symbol_expr) - << "' is not accessible"; + error().source_location=code.find_source_location(); + error() << "constructor of '" + << to_string(symbol_expr) + << "' is not accessible" << eom; throw 0; #endif } diff --git a/src/cpp/cpp_typecheck_compound_type.cpp b/src/cpp/cpp_typecheck_compound_type.cpp index feeb1c6b162..d358bf61680 100644 --- a/src/cpp/cpp_typecheck_compound_type.cpp +++ b/src/cpp/cpp_typecheck_compound_type.cpp @@ -211,8 +211,7 @@ void cpp_typecheckt::typecheck_compound_type( else { error().source_location=type.source_location(); - error() << "error: compound tag '" << base_name - << "' declared previously\n" + error() << "compound tag '" << base_name << "' declared previously\n" << "location of previous definition: " << symbol.location << eom; throw 0; @@ -1522,9 +1521,8 @@ bool cpp_typecheckt::get_component( else { error().source_location=source_location; - error() << "error: member '" << component_name - << "' is not accessible (" << component.get(ID_access) << ")" - << eom; + error() << "member '" << component_name << "' is not accessible (" + << component.get(ID_access) << ")" << eom; throw 0; } } @@ -1566,8 +1564,8 @@ bool cpp_typecheckt::get_component( if(check_component_access(component, final_type)) { error().source_location=source_location; - error() << "error: member '" << component_name - << "' is not accessible" << eom; + error() << "member '" << component_name << "' is not accessible" + << eom; throw 0; } diff --git a/src/cpp/cpp_typecheck_enum_type.cpp b/src/cpp/cpp_typecheck_enum_type.cpp index d01c4e55a36..0fe20a1744a 100644 --- a/src/cpp/cpp_typecheck_enum_type.cpp +++ b/src/cpp/cpp_typecheck_enum_type.cpp @@ -133,8 +133,7 @@ void cpp_typecheckt::typecheck_enum_type(typet &type) if(has_body) { error().source_location=type.source_location(); - error() << "error: enum symbol '" << base_name - << "' declared previously\n" + error() << "enum symbol '" << base_name << "' declared previously\n" << "location of previous definition: " << symbol.location << eom; throw 0; } diff --git a/src/cpp/cpp_typecheck_expr.cpp b/src/cpp/cpp_typecheck_expr.cpp index 1719d3750b7..2685771889c 100644 --- a/src/cpp/cpp_typecheck_expr.cpp +++ b/src/cpp/cpp_typecheck_expr.cpp @@ -145,7 +145,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) if(!standard_conversion_lvalue_to_rvalue(e1, expr.op1())) { error().source_location=e1.find_source_location(); - error() << "error: lvalue to rvalue conversion" << eom; + error() << "lvalue to rvalue conversion" << eom; throw 0; } } @@ -156,7 +156,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) if(!standard_conversion_array_to_pointer(e1, expr.op1())) { error().source_location=e1.find_source_location(); - error() << "error: array to pointer conversion" << eom; + error() << "array to pointer conversion" << eom; throw 0; } } @@ -167,7 +167,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) if(!standard_conversion_function_to_pointer(e1, expr.op1())) { error().source_location=e1.find_source_location(); - error() << "error: function to pointer conversion" << eom; + error() << "function to pointer conversion" << eom; throw 0; } } @@ -178,7 +178,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) if(!standard_conversion_lvalue_to_rvalue(e2, expr.op2())) { error().source_location=e2.find_source_location(); - error() << "error: lvalue to rvalue conversion" << eom; + error() << "lvalue to rvalue conversion" << eom; throw 0; } } @@ -189,7 +189,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) if(!standard_conversion_array_to_pointer(e2, expr.op2())) { error().source_location=e2.find_source_location(); - error() << "error: array to pointer conversion" << eom; + error() << "array to pointer conversion" << eom; throw 0; } } @@ -200,7 +200,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) if(!standard_conversion_function_to_pointer(e2, expr.op2())) { error().source_location=expr.find_source_location(); - error() << "error: function to pointer conversion" << eom; + error() << "function to pointer conversion" << eom; throw 0; } } @@ -217,7 +217,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) else { error().source_location=expr.find_source_location(); - error() << "error: bad types for operands" << eom; + error() << "bad types for operands" << eom; throw 0; } return; @@ -272,7 +272,7 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) else { error().source_location=expr.find_source_location(); - error() << "error: types are incompatible.\n" + error() << "types are incompatible.\n" << "I got '" << type2cpp(expr.op1().type(), *this) << "' and '" << type2cpp(expr.op2().type(), *this) << "'." << eom; throw 0; @@ -706,7 +706,7 @@ void cpp_typecheckt::typecheck_expr_address_of(exprt &expr) if(code_type.get_bool(ID_C_is_virtual)) { error().source_location=expr.source_location(); - error() << "error: pointers to virtual methods" + error() << "pointers to virtual methods" << " are currently not implemented" << eom; throw 0; } @@ -1068,7 +1068,7 @@ void cpp_typecheckt::typecheck_expr_member( if(expr.operands().size()!=1) { error().source_location=expr.find_source_location(); - error() << "error: member operator expects one operand" << eom; + error() << "member operator expects one operand" << eom; throw 0; } @@ -1097,7 +1097,7 @@ void cpp_typecheckt::typecheck_expr_member( if(op0.type().id() != ID_struct_tag && op0.type().id() != ID_union_tag) { error().source_location=expr.find_source_location(); - error() << "error: member operator requires struct/union type " + error() << "member operator requires struct/union type " << "on left hand side but got '" << to_string(op0.type()) << "'" << eom; throw 0; @@ -1113,7 +1113,7 @@ void cpp_typecheckt::typecheck_expr_member( if(type.is_incomplete()) { error().source_location = expr.find_source_location(); - error() << "error: member operator got incomplete type " + error() << "member operator got incomplete type " << "on left hand side" << eom; throw 0; } @@ -1161,7 +1161,7 @@ void cpp_typecheckt::typecheck_expr_member( to_code_type(symbol_expr.type()).return_type().id() == ID_constructor) { error().source_location=expr.find_source_location(); - error() << "error: member '" + error() << "member '" << lookup(symbol_expr.get(ID_identifier)).base_name << "' is a constructor" << eom; throw 0; @@ -1175,7 +1175,7 @@ void cpp_typecheckt::typecheck_expr_member( if(pcomp.is_nil()) { error().source_location=expr.find_source_location(); - error() << "error: '" << symbol_expr.get(ID_identifier) + error() << "'" << symbol_expr.get(ID_identifier) << "' is not static member " << "of class '" << to_string(op0.type()) << "'" << eom; throw 0; @@ -1217,8 +1217,8 @@ void cpp_typecheckt::typecheck_expr_member( else { error().source_location=expr.find_source_location(); - error() << "error: member '" << component_name << "' of '" - << to_string(type) << "' not found" << eom; + error() << "member '" << component_name << "' of '" << to_string(type) + << "' not found" << eom; throw 0; } @@ -1243,7 +1243,7 @@ void cpp_typecheckt::typecheck_expr_ptrmember( if(expr.operands().size()!=1) { error().source_location=expr.find_source_location(); - error() << "error: ptrmember operator expects one operand" << eom; + error() << "ptrmember operator expects one operand" << eom; throw 0; } @@ -1254,7 +1254,7 @@ void cpp_typecheckt::typecheck_expr_ptrmember( if(op.type().id() != ID_pointer) { error().source_location=expr.find_source_location(); - error() << "error: ptrmember operator requires pointer type " + error() << "ptrmember operator requires pointer type " << "on left hand side, but got '" << to_string(op.type()) << "'" << eom; throw 0; diff --git a/src/cpp/cpp_typecheck_resolve.cpp b/src/cpp/cpp_typecheck_resolve.cpp index 37d4d529dc4..d0d84a3612f 100644 --- a/src/cpp/cpp_typecheck_resolve.cpp +++ b/src/cpp/cpp_typecheck_resolve.cpp @@ -1675,9 +1675,8 @@ exprt cpp_typecheck_resolvet::resolve( return nil_exprt(); cpp_typecheck.error().source_location=result.source_location()); - cpp_typecheck.str - << "error: member '" << result.get(ID_component_name) - << "' is not accessible"; + cpp_typecheck.error() << "member '" << result.get(ID_component_name) + << "' is not accessible" << messaget::eom; throw 0; #endif } @@ -1693,7 +1692,7 @@ exprt cpp_typecheck_resolvet::resolve( cpp_typecheck.error().source_location=source_location; cpp_typecheck.error() - << "error: expected expression, but got type '" + << "expected expression, but got type '" << cpp_typecheck.to_string(result.type()) << "'" << messaget::eom; throw 0; @@ -1709,7 +1708,7 @@ exprt cpp_typecheck_resolvet::resolve( cpp_typecheck.error().source_location=source_location; cpp_typecheck.error() - << "error: expected type, but got expression '" + << "expected type, but got expression '" << cpp_typecheck.to_string(result) << "'" << messaget::eom; throw 0; diff --git a/src/cpp/cpp_typecheck_type.cpp b/src/cpp/cpp_typecheck_type.cpp index 40e709b670a..271eb8e1dfa 100644 --- a/src/cpp/cpp_typecheck_type.cpp +++ b/src/cpp/cpp_typecheck_type.cpp @@ -61,7 +61,7 @@ void cpp_typecheckt::typecheck_type(typet &type) if(symbol_expr.id()!=ID_type) { error().source_location=type.source_location(); - error() << "error: expected type" << eom; + error() << "expected type" << eom; throw 0; } diff --git a/src/goto-programs/builtin_functions.cpp b/src/goto-programs/builtin_functions.cpp index 9277593a30e..34e2078306b 100644 --- a/src/goto-programs/builtin_functions.cpp +++ b/src/goto-programs/builtin_functions.cpp @@ -818,15 +818,15 @@ void goto_convertt::do_function_call_symbol( if(ns.lookup(identifier, symbol)) { error().source_location=function.find_source_location(); - error() << "error: function '" << identifier << "' not found" << eom; + error() << "function '" << identifier << "' not found" << eom; throw 0; } if(symbol->type.id()!=ID_code) { error().source_location=function.find_source_location(); - error() << "error: function '" << identifier - << "' type mismatch: expected code" << eom; + error() << "function '" << identifier << "' type mismatch: expected code" + << eom; throw 0; } diff --git a/src/linking/linking.cpp b/src/linking/linking.cpp index b4ba95fab2f..a5c11955b1e 100644 --- a/src/linking/linking.cpp +++ b/src/linking/linking.cpp @@ -492,8 +492,7 @@ void linkingt::link_error( messaget log{message_handler}; log.error().source_location = new_symbol.location; - log.error() << "error: " << msg << " '" << old_symbol.display_name() << "'" - << '\n'; + log.error() << msg << " '" << old_symbol.display_name() << "'" << '\n'; log.error() << "old definition in module '" << old_symbol.module << "' " << old_symbol.location << '\n' << type_to_string_verbose(old_symbol) << '\n'; @@ -510,8 +509,7 @@ void linkingt::link_warning( messaget log{message_handler}; log.warning().source_location = new_symbol.location; - log.warning() << "warning: " << msg << " \"" << old_symbol.display_name() - << "\"" << '\n'; + log.warning() << msg << " '" << old_symbol.display_name() << "'\n"; log.warning() << "old definition in module " << old_symbol.module << " " << old_symbol.location << '\n' << type_to_string_verbose(old_symbol) << '\n'; @@ -1160,8 +1158,8 @@ void linkingt::duplicate_object_symbol( messaget log{message_handler}; log.warning().source_location = new_symbol.location; - log.warning() << "warning: conflicting initializers for" - << " variable \"" << old_symbol.name << "\"\n"; + log.warning() << "conflicting initializers for" + << " variable '" << old_symbol.name << "'\n"; log.warning() << "using old value in module " << old_symbol.module << " " << old_symbol.value.find_source_location() << '\n' << expr_to_string(old_symbol.name, tmp_old) << '\n'; From 587824fd180ce4a0a6ee4421e12b69b5c25138fd Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 4 Jan 2021 12:50:06 +0000 Subject: [PATCH 2/3] goto-cc modes: interpret command-line options to set default verbosity to warning We already did this for GCC, but we can also do this for other modes (ARMCC, CodeWarrior, LD, CL, LINK). --- src/goto-cc/armcc_mode.cpp | 4 +++- src/goto-cc/cw_mode.cpp | 4 +++- src/goto-cc/ld_mode.cpp | 5 ++++- src/goto-cc/ms_cl_mode.cpp | 5 ++++- src/goto-cc/ms_link_mode.cpp | 2 +- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/goto-cc/armcc_mode.cpp b/src/goto-cc/armcc_mode.cpp index 7aeed628008..7150ffe82f6 100644 --- a/src/goto-cc/armcc_mode.cpp +++ b/src/goto-cc/armcc_mode.cpp @@ -45,8 +45,10 @@ int armcc_modet::doit() has_prefix(base_name, "goto-link"); #endif + const auto default_verbosity = + cmdline.isset("diag_warning=") ? messaget::M_WARNING : messaget::M_ERROR; const auto verbosity = messaget::eval_verbosity( - cmdline.get_value("verbosity"), messaget::M_ERROR, message_handler); + cmdline.get_value("verbosity"), default_verbosity, message_handler); messaget log{message_handler}; log.debug() << "ARM mode" << messaget::eom; diff --git a/src/goto-cc/cw_mode.cpp b/src/goto-cc/cw_mode.cpp index b4a3452a9a4..1d566a8afa1 100644 --- a/src/goto-cc/cw_mode.cpp +++ b/src/goto-cc/cw_mode.cpp @@ -45,8 +45,10 @@ int cw_modet::doit() has_prefix(base_name, "goto-link"); #endif + const auto default_verbosity = + cmdline.isset("Wall") ? messaget::M_WARNING : messaget::M_ERROR; const auto verbosity = messaget::eval_verbosity( - cmdline.get_value("verbosity"), messaget::M_ERROR, message_handler); + cmdline.get_value("verbosity"), default_verbosity, message_handler); messaget log{message_handler}; log.debug() << "CodeWarrior mode" << messaget::eom; diff --git a/src/goto-cc/ld_mode.cpp b/src/goto-cc/ld_mode.cpp index bee843fa3fa..f24235259cf 100644 --- a/src/goto-cc/ld_mode.cpp +++ b/src/goto-cc/ld_mode.cpp @@ -78,7 +78,10 @@ int ld_modet::doit() messaget::eval_verbosity( cmdline.get_value("verbosity"), messaget::M_ERROR, gcc_message_handler); - compilet compiler(cmdline, gcc_message_handler, false); + compilet compiler( + cmdline, + gcc_message_handler, + cmdline.isset("fatal-warnings") && !cmdline.isset("no-fatal-warnings")); // determine actions to be undertaken compiler.mode = compilet::LINK_LIBRARY; diff --git a/src/goto-cc/ms_cl_mode.cpp b/src/goto-cc/ms_cl_mode.cpp index bbc78a165b1..a8c0ab077aa 100644 --- a/src/goto-cc/ms_cl_mode.cpp +++ b/src/goto-cc/ms_cl_mode.cpp @@ -56,8 +56,11 @@ int ms_cl_modet::doit() has_prefix(base_name, "goto-link"); #endif + const auto default_verbosity = (cmdline.isset("Wall") || cmdline.isset("W4")) + ? messaget::M_WARNING + : messaget::M_ERROR; const auto verbosity = messaget::eval_verbosity( - cmdline.get_value("verbosity"), messaget::M_ERROR, message_handler); + cmdline.get_value("verbosity"), default_verbosity, message_handler); ms_cl_versiont ms_cl_version; ms_cl_version.get("cl.exe"); diff --git a/src/goto-cc/ms_link_mode.cpp b/src/goto-cc/ms_link_mode.cpp index d494c834f63..51affadc181 100644 --- a/src/goto-cc/ms_link_mode.cpp +++ b/src/goto-cc/ms_link_mode.cpp @@ -36,7 +36,7 @@ int ms_link_modet::doit() messaget::eval_verbosity( cmdline.get_value("verbosity"), messaget::M_ERROR, message_handler); - compilet compiler(cmdline, message_handler, false); + compilet compiler(cmdline, message_handler, cmdline.isset("WX")); // determine actions to be undertaken compiler.mode = compilet::LINK_LIBRARY; From 613289bc04d84414218572c4b8e20598818c042e Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 4 Jan 2021 12:54:53 +0000 Subject: [PATCH 3/3] GCC and CL message handler: print warnings as errors We already treated warnings as errors (if requested via command-line options), but we should also mimic the output presented by CL/GCC with those command-line options set. --- src/goto-cc/armcc_mode.cpp | 1 + src/goto-cc/as_mode.cpp | 1 + src/goto-cc/cl_message_handler.cpp | 3 +++ src/goto-cc/cl_message_handler.h | 10 ++++++++++ src/goto-cc/gcc_message_handler.cpp | 6 +++++- src/goto-cc/gcc_message_handler.h | 10 ++++++++++ src/goto-cc/gcc_mode.cpp | 2 ++ src/goto-cc/ld_mode.cpp | 2 ++ src/goto-cc/ms_cl_mode.cpp | 1 + src/goto-cc/ms_link_mode.cpp | 1 + 10 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/goto-cc/armcc_mode.cpp b/src/goto-cc/armcc_mode.cpp index 7150ffe82f6..bacd0eee185 100644 --- a/src/goto-cc/armcc_mode.cpp +++ b/src/goto-cc/armcc_mode.cpp @@ -49,6 +49,7 @@ int armcc_modet::doit() cmdline.isset("diag_warning=") ? messaget::M_WARNING : messaget::M_ERROR; const auto verbosity = messaget::eval_verbosity( cmdline.get_value("verbosity"), default_verbosity, message_handler); + message_handler.print_warnings_as_errors(cmdline.isset("diag_error=")); messaget log{message_handler}; log.debug() << "ARM mode" << messaget::eom; diff --git a/src/goto-cc/as_mode.cpp b/src/goto-cc/as_mode.cpp index fee687b2a9e..805b82b6095 100644 --- a/src/goto-cc/as_mode.cpp +++ b/src/goto-cc/as_mode.cpp @@ -110,6 +110,7 @@ int as_modet::doit() messaget::M_WARNING : messaget::M_ERROR; messaget::eval_verbosity( cmdline.get_value("verbosity"), default_verbosity, message_handler); + message_handler.print_warnings_as_errors(cmdline.isset("fatal-warnings")); if(act_as_as86) { diff --git a/src/goto-cc/cl_message_handler.cpp b/src/goto-cc/cl_message_handler.cpp index c2eb19456a5..e68d1221d5e 100644 --- a/src/goto-cc/cl_message_handler.cpp +++ b/src/goto-cc/cl_message_handler.cpp @@ -25,6 +25,9 @@ void cl_message_handlert::print( std::ostringstream formatted_message; + if(level == messaget::M_WARNING && warnings_are_errors) + formatted_message << "error: warning treated as error\n"; + const irep_idt file = location.get_file(); const std::string &line = id2string(location.get_line()); formatted_message << file << '(' << line << "): "; diff --git a/src/goto-cc/cl_message_handler.h b/src/goto-cc/cl_message_handler.h index 7a86d4d0b1d..3eaf91cd7d7 100644 --- a/src/goto-cc/cl_message_handler.h +++ b/src/goto-cc/cl_message_handler.h @@ -29,6 +29,16 @@ class cl_message_handlert : public console_message_handlert const source_locationt &location) override; using console_message_handlert::print; + + /// With \p yes set to \c true, prefix warnings with an error message. + /// \param yes: Whether or not to prefix warnings. + void print_warnings_as_errors(bool yes) + { + warnings_are_errors = yes; + } + +private: + bool warnings_are_errors = false; }; #endif // CPROVER_GOTO_CC_CL_MESSAGE_HANDLER_H diff --git a/src/goto-cc/gcc_message_handler.cpp b/src/goto-cc/gcc_message_handler.cpp index 814dd836863..0239266feca 100644 --- a/src/goto-cc/gcc_message_handler.cpp +++ b/src/goto-cc/gcc_message_handler.cpp @@ -53,8 +53,12 @@ void gcc_message_handlert::print( else out << column << ": "; - if(level == messaget::M_ERROR) + if( + level == messaget::M_ERROR || + (level == messaget::M_WARNING && warnings_are_errors)) + { out << string(messaget::red) << "error: "; + } else if(level == messaget::M_WARNING) out << string(messaget::bright_magenta) << "warning: "; diff --git a/src/goto-cc/gcc_message_handler.h b/src/goto-cc/gcc_message_handler.h index 45b3fd0c51e..37b5f8a4c59 100644 --- a/src/goto-cc/gcc_message_handler.h +++ b/src/goto-cc/gcc_message_handler.h @@ -30,7 +30,17 @@ class gcc_message_handlert : public console_message_handlert const std::string &message, const source_locationt &location) override; + /// With \p yes set to \c true, prefix warnings with "error:" instead of + /// "warning:". + /// \param yes: Whether or not to prefix warnings with "error:". + void print_warnings_as_errors(bool yes) + { + warnings_are_errors = yes; + } + private: + bool warnings_are_errors = false; + /// feed a command into a string std::string string(const messaget::commandt &c) const { diff --git a/src/goto-cc/gcc_mode.cpp b/src/goto-cc/gcc_mode.cpp index 85fe6831e3b..955ba856ba3 100644 --- a/src/goto-cc/gcc_mode.cpp +++ b/src/goto-cc/gcc_mode.cpp @@ -315,6 +315,8 @@ int gcc_modet::doit() messaget::M_WARNING : messaget::M_ERROR; messaget::eval_verbosity( cmdline.get_value("verbosity"), default_verbosity, gcc_message_handler); + gcc_message_handler.print_warnings_as_errors( + cmdline.isset("Werror") && !cmdline.isset("Wno-error")); bool act_as_bcc= base_name=="bcc" || diff --git a/src/goto-cc/ld_mode.cpp b/src/goto-cc/ld_mode.cpp index f24235259cf..6dabb29e759 100644 --- a/src/goto-cc/ld_mode.cpp +++ b/src/goto-cc/ld_mode.cpp @@ -77,6 +77,8 @@ int ld_modet::doit() messaget::eval_verbosity( cmdline.get_value("verbosity"), messaget::M_ERROR, gcc_message_handler); + gcc_message_handler.print_warnings_as_errors( + cmdline.isset("fatal-warnings") && !cmdline.isset("no-fatal-warnings")); compilet compiler( cmdline, diff --git a/src/goto-cc/ms_cl_mode.cpp b/src/goto-cc/ms_cl_mode.cpp index a8c0ab077aa..ca125497ffb 100644 --- a/src/goto-cc/ms_cl_mode.cpp +++ b/src/goto-cc/ms_cl_mode.cpp @@ -61,6 +61,7 @@ int ms_cl_modet::doit() : messaget::M_ERROR; const auto verbosity = messaget::eval_verbosity( cmdline.get_value("verbosity"), default_verbosity, message_handler); + message_handler.print_warnings_as_errors(cmdline.isset("WX")); ms_cl_versiont ms_cl_version; ms_cl_version.get("cl.exe"); diff --git a/src/goto-cc/ms_link_mode.cpp b/src/goto-cc/ms_link_mode.cpp index 51affadc181..6f9129ad421 100644 --- a/src/goto-cc/ms_link_mode.cpp +++ b/src/goto-cc/ms_link_mode.cpp @@ -35,6 +35,7 @@ int ms_link_modet::doit() messaget::eval_verbosity( cmdline.get_value("verbosity"), messaget::M_ERROR, message_handler); + message_handler.print_warnings_as_errors(cmdline.isset("WX")); compilet compiler(cmdline, message_handler, cmdline.isset("WX"));