diff options
author | Naveen Seth Hanig <naveen.hanig@outlook.com> | 2025-05-15 15:36:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-15 09:36:28 -0400 |
commit | 636628d8fde45fc2bb99a1016f7503d0e744ab89 (patch) | |
tree | 2a1b4ad3a99c058d9b9e9d8c7a6e27379c439ad6 /clang | |
parent | a2f156b84ab124ccfbbe2bd6cbbdb2f3bcbba0ce (diff) | |
download | llvm-636628d8fde45fc2bb99a1016f7503d0e744ab89.zip llvm-636628d8fde45fc2bb99a1016f7503d0e744ab89.tar.gz llvm-636628d8fde45fc2bb99a1016f7503d0e744ab89.tar.bz2 |
[clang] Enforce 1-based indexing for command line source locations (#139457)
Fixes #139375
Clang expects command line source locations to be provided using 1-based
indexing.
Currently, Clang does not reject zero as invalid argument for column or
line number, which can cause Clang to crash.
This commit extends validation in `ParsedSourceLocation::FromString` to
only accept (unsinged) non-zero integers.
Diffstat (limited to 'clang')
-rw-r--r-- | clang/docs/ReleaseNotes.rst | 7 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.td | 4 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CommandLineSourceLoc.h | 11 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 6 | ||||
-rw-r--r-- | clang/test/CodeCompletion/source-loc-zero.cpp | 11 | ||||
-rw-r--r-- | clang/test/Refactor/source-loc-zero.cpp | 17 | ||||
-rw-r--r-- | clang/tools/clang-refactor/ClangRefactor.cpp | 3 |
7 files changed, 54 insertions, 5 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1f17bc6..e9ad113 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -859,6 +859,11 @@ clang-format - Add ``OneLineFormatOffRegex`` option for turning formatting off for one line. - Add ``SpaceAfterOperatorKeyword`` option. +clang-refactor +-------------- +- Reject `0` as column or line number in 1-based command-line source locations. + Fixes crash caused by `0` input in `-selection=<file>:<line>:<column>[-<line>:<column>]`. (#GH139457) + libclang -------- - Fixed a bug in ``clang_File_isEqual`` that sometimes led to different @@ -877,6 +882,8 @@ libclang Code Completion --------------- +- Reject `0` as column or line number in 1-based command-line source locations. + Fixes crash caused by `0` input in `-code-completion-at=<file>:<line>:<column>`. (#GH139457) Static Analyzer --------------- diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index b15cba6..4da8f80 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -670,6 +670,10 @@ def note_drv_verify_prefix_spelling : Note< "-verify prefixes must start with a letter and contain only alphanumeric" " characters, hyphens, and underscores">; +def note_command_line_code_loc_requirement + : Note<"-code-completion-at=<file>:<line>:<column> requires <line> and " + "<column> to be integers greater than zero">; + def warn_drv_global_isel_incomplete : Warning< "-fglobal-isel support for the '%0' architecture is incomplete">, InGroup<GlobalISel>; diff --git a/clang/include/clang/Frontend/CommandLineSourceLoc.h b/clang/include/clang/Frontend/CommandLineSourceLoc.h index 074800a..b07ffcb 100644 --- a/clang/include/clang/Frontend/CommandLineSourceLoc.h +++ b/clang/include/clang/Frontend/CommandLineSourceLoc.h @@ -24,7 +24,9 @@ namespace clang { /// A source location that has been parsed on the command line. struct ParsedSourceLocation { std::string FileName; + // The 1-based line number unsigned Line; + // The 1-based column number unsigned Column; public: @@ -38,7 +40,8 @@ public: // If both tail splits were valid integers, return success. if (!ColSplit.second.getAsInteger(10, PSL.Column) && - !LineSplit.second.getAsInteger(10, PSL.Line)) { + !LineSplit.second.getAsInteger(10, PSL.Line) && + !(PSL.Column == 0 || PSL.Line == 0)) { PSL.FileName = std::string(LineSplit.first); // On the command-line, stdin may be specified via "-". Inside the @@ -89,8 +92,12 @@ struct ParsedSourceRange { // probably belongs to the filename which menas the whole // string should be parsed. RangeSplit.first = Str; - } else + } else { + // Column and line numbers are 1-based. + if (EndLine == 0 || EndColumn == 0) + return std::nullopt; HasEndLoc = true; + } } auto Begin = ParsedSourceLocation::FromString(RangeSplit.first); if (Begin.FileName.empty()) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3945129..fd48e42 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3112,9 +3112,11 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) { Opts.CodeCompletionAt = ParsedSourceLocation::FromString(A->getValue()); - if (Opts.CodeCompletionAt.FileName.empty()) + if (Opts.CodeCompletionAt.FileName.empty()) { Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << A->getValue(); + << A->getAsString(Args) << A->getValue(); + Diags.Report(diag::note_command_line_code_loc_requirement); + } } Opts.Plugins = Args.getAllArgValues(OPT_load); diff --git a/clang/test/CodeCompletion/source-loc-zero.cpp b/clang/test/CodeCompletion/source-loc-zero.cpp new file mode 100644 index 0000000..a428c15 --- /dev/null +++ b/clang/test/CodeCompletion/source-loc-zero.cpp @@ -0,0 +1,11 @@ +// Regression test for #139375 +// Clang uses 1-based indexing for source locations given from the command-line. +// Verify that Clang rejects 0 as an invalid value for line or column number. + +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:0:1 %s -o - 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-DIAG %s +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:1:0 %s -o - 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-DIAG %s + +// CHECK-DIAG: error: invalid value '{{.*}}' in '-code-completion-at={{.*}}' +// CHECK-NEXT: hint: -code-completion-at=<file>:<line>:<column> requires <line> and <column> to be integers greater than zero diff --git a/clang/test/Refactor/source-loc-zero.cpp b/clang/test/Refactor/source-loc-zero.cpp new file mode 100644 index 0000000..61b7827 --- /dev/null +++ b/clang/test/Refactor/source-loc-zero.cpp @@ -0,0 +1,17 @@ +// Regression test for #139375 +// Clang uses 1-based indexing for source locations given from the command-line. +// Verify that `clang-refactor` rejects 0 as an invalid value for line or column number. + +// For range start: +// RUN: not clang-refactor local-rename -selection=%s:0:1-1:1 -new-name=test %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-DIAG %s +// RUN: not clang-refactor local-rename -selection=%s:1:0-1:1 -new-name=test %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-DIAG %s + +// For range end: +// RUN: not clang-refactor local-rename -selection=%s:1:1-0:1 -new-name=test %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-DIAG %s +// RUN: not clang-refactor local-rename -selection=%s:1:1-1:0 -new-name=test %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-DIAG %s + +// CHECK-DIAG: error: '-selection' option must be specified using <file>:<line>:<column> or <file>:<line>:<column>-<line>:<column> format, where <line> and <column> are integers greater than zero. diff --git a/clang/tools/clang-refactor/ClangRefactor.cpp b/clang/tools/clang-refactor/ClangRefactor.cpp index 968f059..a92b3f9 100644 --- a/clang/tools/clang-refactor/ClangRefactor.cpp +++ b/clang/tools/clang-refactor/ClangRefactor.cpp @@ -160,7 +160,8 @@ SourceSelectionArgument::fromString(StringRef Value) { return std::make_unique<SourceRangeSelectionArgument>(std::move(*Range)); llvm::errs() << "error: '-selection' option must be specified using " "<file>:<line>:<column> or " - "<file>:<line>:<column>-<line>:<column> format\n"; + "<file>:<line>:<column>-<line>:<column> format, " + "where <line> and <column> are integers greater than zero.\n"; return nullptr; } |