From a09b8b9c025dd69da07168096aa00be1f6949c49 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 22 May 2023 13:08:00 +0100 Subject: [PATCH] solc does not warn or error for duplicate @param tags (#1320) Make it a warning and add note to previous doc tag, and fix the locations. Signed-off-by: Sean Young --- src/sema/tags.rs | 11 +++++++---- .../substrate/tags/event_tag_02.sol | 4 +++- .../substrate/tags/functions_02.sol | 5 ++++- .../substrate/tags/struct_tag_02.sol | 3 ++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/sema/tags.rs b/src/sema/tags.rs index 882f42b38..2e03c5ef6 100644 --- a/src/sema/tags.rs +++ b/src/sema/tags.rs @@ -19,7 +19,7 @@ pub fn resolve_tags( for c in tags.iter().flat_map(DocComment::comments) { let tag_loc = pt::Loc::File(file_no, c.tag_offset, c.tag_offset + c.tag.len() + 1); let value_loc = pt::Loc::File(file_no, c.value_offset, c.value_offset + c.value.len()); - let loc = pt::Loc::File(file_no, c.tag_offset, c.value_offset + c.value.len()); + let loc = pt::Loc::File(file_no, c.tag_offset - 1, c.value_offset + c.value.len()); match c.tag.as_str() { "notice" | "author" | "title" | "dev" => { @@ -49,10 +49,13 @@ pub fn resolve_tags( let value = v.get(1).unwrap_or(&"").to_string(); if let Some(no) = params.unwrap().iter().position(|p| p.name_as_str() == name) { - if res.iter().any(|e| e.tag == "param" && e.no == no) { - ns.diagnostics.push(Diagnostic::error( - tag_loc, + if let Some(other) = res.iter().find(|e| e.tag == "param" && e.no == no) { + // Note: solc does not detect this problem + ns.diagnostics.push(Diagnostic::warning_with_note( + loc, format!("duplicate tag '@param' for '{name}'"), + other.loc, + format!("previous tag '@param' for '{name}'"), )); } else { res.push(Tag { diff --git a/tests/contract_testcases/substrate/tags/event_tag_02.sol b/tests/contract_testcases/substrate/tags/event_tag_02.sol index 375f07b3a..abc0a93ab 100644 --- a/tests/contract_testcases/substrate/tags/event_tag_02.sol +++ b/tests/contract_testcases/substrate/tags/event_tag_02.sol @@ -5,4 +5,6 @@ uint32 f ); // ---- Expect: diagnostics ---- -// error: 3:14-20: duplicate tag '@param' for 'f' +// warning: 3:13-25: duplicate tag '@param' for 'f' +// note 2:13-27: previous tag '@param' for 'f' +// warning: 4:15-16: event 'x' has never been emitted diff --git a/tests/contract_testcases/substrate/tags/functions_02.sol b/tests/contract_testcases/substrate/tags/functions_02.sol index 66015c86c..4ab572724 100644 --- a/tests/contract_testcases/substrate/tags/functions_02.sol +++ b/tests/contract_testcases/substrate/tags/functions_02.sol @@ -7,4 +7,7 @@ function foo(int f) public {} } // ---- Expect: diagnostics ---- -// error: 5:15-21: duplicate tag '@param' for 'f' +// warning: 5:14-27: duplicate tag '@param' for 'f' +// note 3:17-25: previous tag '@param' for 'f' +// warning: 7:13-39: function can be declared 'pure' +// warning: 7:30-31: function parameter 'f' has never been read diff --git a/tests/contract_testcases/substrate/tags/struct_tag_02.sol b/tests/contract_testcases/substrate/tags/struct_tag_02.sol index fbd4de31a..c9100dfb2 100644 --- a/tests/contract_testcases/substrate/tags/struct_tag_02.sol +++ b/tests/contract_testcases/substrate/tags/struct_tag_02.sol @@ -5,4 +5,5 @@ uint32 f; } // ---- Expect: diagnostics ---- -// error: 3:14-20: duplicate tag '@param' for 'f' +// warning: 3:13-25: duplicate tag '@param' for 'f' +// note 2:13-27: previous tag '@param' for 'f' \ No newline at end of file