Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,16 @@ static bool parseFileExtensions(llvm::ArrayRef<std::string> AllFileExtensions,
void ClangTidyContext::setCurrentFile(StringRef File) {
CurrentFile = std::string(File);
CurrentOptions = getOptionsForFile(CurrentFile);
CheckFilter = std::make_unique<CachedGlobList>(*getOptions().Checks);
WarningAsErrorFilter =
std::make_unique<CachedGlobList>(*getOptions().WarningsAsErrors);
if (!parseFileExtensions(*getOptions().HeaderFileExtensions,
CheckFilter =
std::make_unique<CachedGlobList>(getOptions().Checks.value_or(""));
WarningAsErrorFilter = std::make_unique<CachedGlobList>(
getOptions().WarningsAsErrors.value_or(""));
if (!parseFileExtensions(getOptions().HeaderFileExtensions.value_or(
std::vector<std::string>()),
HeaderFileExtensions))
this->configurationDiag("Invalid header file extensions");
if (!parseFileExtensions(*getOptions().ImplementationFileExtensions,
if (!parseFileExtensions(getOptions().ImplementationFileExtensions.value_or(
std::vector<std::string>()),
ImplementationFileExtensions))
this->configurationDiag("Invalid implementation file extensions");
}
Expand Down Expand Up @@ -569,7 +572,7 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
return;
}

if (!*Context.getOptions().SystemHeaders &&
if (!Context.getOptions().SystemHeaders.value_or(false) &&
(Sources.isInSystemHeader(Location) || Sources.isInSystemMacro(Location)))
return;

Expand Down Expand Up @@ -600,15 +603,15 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,

llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
if (!HeaderFilter)
HeaderFilter =
std::make_unique<llvm::Regex>(*Context.getOptions().HeaderFilterRegex);
HeaderFilter = std::make_unique<llvm::Regex>(
Context.getOptions().HeaderFilterRegex.value_or(""));
return HeaderFilter.get();
}

llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
if (!ExcludeHeaderFilter)
ExcludeHeaderFilter = std::make_unique<llvm::Regex>(
*Context.getOptions().ExcludeHeaderFilterRegex);
Context.getOptions().ExcludeHeaderFilterRegex.value_or(""));
return ExcludeHeaderFilter.get();
}

Expand Down
22 changes: 11 additions & 11 deletions clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,21 @@ void ClangTidyProfiling::printUserFriendlyTable(llvm::raw_ostream &OS,
}

void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS,
llvm::TimerGroup &TG) {
llvm::TimerGroup &TG,
const StorageParams &Storage) {
OS << "{\n";
OS << R"("file": ")" << Storage->SourceFilename << "\",\n";
OS << R"("timestamp": ")" << Storage->Timestamp << "\",\n";
OS << R"("file": ")" << Storage.SourceFilename << "\",\n";
OS << R"("timestamp": ")" << Storage.Timestamp << "\",\n";
OS << "\"profile\": {\n";
TG.printJSONValues(OS, "");
OS << "\n}\n";
OS << "}\n";
OS.flush();
}

void ClangTidyProfiling::storeProfileData(llvm::TimerGroup &TG) {
assert(Storage && "We should have a filename.");
Copy link
Member Author

@zeyi2 zeyi2 Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix the removal of this assert soon.


llvm::SmallString<256> OutputDirectory(Storage->StoreFilename);
void ClangTidyProfiling::storeProfileData(llvm::TimerGroup &TG,
const StorageParams &Storage) {
llvm::SmallString<256> OutputDirectory(Storage.StoreFilename);
llvm::sys::path::remove_filename(OutputDirectory);
if (const std::error_code EC =
llvm::sys::fs::create_directories(OutputDirectory)) {
Expand All @@ -67,14 +67,14 @@ void ClangTidyProfiling::storeProfileData(llvm::TimerGroup &TG) {
}

std::error_code EC;
llvm::raw_fd_ostream OS(Storage->StoreFilename, EC, llvm::sys::fs::OF_None);
llvm::raw_fd_ostream OS(Storage.StoreFilename, EC, llvm::sys::fs::OF_None);
if (EC) {
llvm::errs() << "Error opening output file '" << Storage->StoreFilename
llvm::errs() << "Error opening output file '" << Storage.StoreFilename
<< "': " << EC.message() << "\n";
return;
}

printAsJSON(OS, TG);
printAsJSON(OS, TG, Storage);
}

ClangTidyProfiling::ClangTidyProfiling(std::optional<StorageParams> Storage)
Expand All @@ -85,7 +85,7 @@ ClangTidyProfiling::~ClangTidyProfiling() {
if (!Storage)
printUserFriendlyTable(llvm::errs(), TG);
else
storeProfileData(TG);
storeProfileData(TG, *Storage);
}

} // namespace clang::tidy
5 changes: 3 additions & 2 deletions clang-tools-extra/clang-tidy/ClangTidyProfiling.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ class ClangTidyProfiling {
std::optional<StorageParams> Storage;

void printUserFriendlyTable(llvm::raw_ostream &OS, llvm::TimerGroup &TG);
void printAsJSON(llvm::raw_ostream &OS, llvm::TimerGroup &TG);
void storeProfileData(llvm::TimerGroup &TG);
void printAsJSON(llvm::raw_ostream &OS, llvm::TimerGroup &TG,
const StorageParams &Storage);
void storeProfileData(llvm::TimerGroup &TG, const StorageParams &Storage);

public:
llvm::StringMap<llvm::TimeRecord> Records;
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ void TimeSubtractionCheck::registerMatchers(MatchFinder *Finder) {
const std::string TimeInverse = (llvm::Twine("ToUnix") + ScaleName).str();
std::optional<DurationScale> Scale = getScaleForTimeInverse(TimeInverse);
assert(Scale && "Unknown scale encountered");
if (!Scale)
continue;
Comment on lines 98 to +100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we then remove first assert if we still check via if later? (but preserve comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels weird that dataflow framework didn't count it as "validation", could it be a FP?
Later, you used assert(BestConversion && "text"); for the same purpose of validation


auto TimeInverseMatcher = callExpr(callee(
functionDecl(hasName((llvm::Twine("::absl::") + TimeInverse).str()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1690,8 +1690,9 @@ class PassedToSameFunction {
TargetIdx.emplace(Idx);

assert(TargetIdx && "Matched, but didn't find index?");
TargetParams[PassedParamOfThisFn].insert(
{CalledFn->getCanonicalDecl(), *TargetIdx});
if (TargetIdx)
TargetParams[PassedParamOfThisFn].insert(
{CalledFn->getCanonicalDecl(), *TargetIdx});
}
}

Expand Down
10 changes: 6 additions & 4 deletions clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,12 @@ void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) {
<< ActualNumberParameters << ParameterThreshold.value();
}

for (const auto &CSPos : FI.NestingThresholders) {
diag(CSPos, "nesting level %0 starts here (threshold %1)",
DiagnosticIDs::Note)
<< NestingThreshold.value() + 1 << NestingThreshold.value();
if (NestingThreshold) {
for (const auto &CSPos : FI.NestingThresholders) {
diag(CSPos, "nesting level %0 starts here (threshold %1)",
DiagnosticIDs::Note)
<< NestingThreshold.value() + 1 << NestingThreshold.value();
}
}

if (VariableThreshold && FI.Variables > VariableThreshold) {
Expand Down
26 changes: 16 additions & 10 deletions clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ bool IdentifierNamingCheck::HungarianNotation::isOptionEnabled(
if (Iter == StrMap.end())
return false;

return *llvm::yaml::parseBool(Iter->getValue());
return llvm::yaml::parseBool(Iter->getValue()).value_or(false);
}

void IdentifierNamingCheck::HungarianNotation::loadFileConfig(
Expand Down Expand Up @@ -834,26 +834,28 @@ void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
const ArrayRef<std::optional<NamingStyle>> Styles =
MainFileStyle->getStyles();
for (size_t I = 0; I < SK_Count; ++I) {
if (!Styles[I])
const auto &StyleOpt = Styles[I];
if (!StyleOpt)
continue;
const NamingStyle &Style = *StyleOpt;
const size_t StyleSize = StyleNames[I].size();
StyleString.assign({StyleNames[I], "HungarianPrefix"});

Options.store(Opts, StyleString, Styles[I]->HPType);
Options.store(Opts, StyleString, Style.HPType);

memcpy(&StyleString[StyleSize], "IgnoredRegexp", 13);
StyleString.truncate(StyleSize + 13);
Options.store(Opts, StyleString, Styles[I]->IgnoredRegexpStr);
Options.store(Opts, StyleString, Style.IgnoredRegexpStr);
memcpy(&StyleString[StyleSize], "Prefix", 6);
StyleString.truncate(StyleSize + 6);
Options.store(Opts, StyleString, Styles[I]->Prefix);
Options.store(Opts, StyleString, Style.Prefix);
// Fast replacement of [Pre]fix -> [Suf]fix.
memcpy(&StyleString[StyleSize], "Suf", 3);
Options.store(Opts, StyleString, Styles[I]->Suffix);
if (Styles[I]->Case) {
Options.store(Opts, StyleString, Style.Suffix);
if (Style.Case) {
memcpy(&StyleString[StyleSize], "Case", 4);
StyleString.pop_back_n(2);
Options.store(Opts, StyleString, *Styles[I]->Case);
Options.store(Opts, StyleString, *Style.Case);
}
}
Options.store(Opts, "GetConfigPerFile", GetConfigPerFile);
Expand Down Expand Up @@ -1344,10 +1346,14 @@ IdentifierNamingCheck::getFailureInfo(
ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
const IdentifierNamingCheck::HungarianNotationOption &HNOption,
StyleKind SK, const SourceManager &SM, bool IgnoreFailedSplit) const {
if (SK == SK_Invalid || !NamingStyles[SK])
if (SK == SK_Invalid)
return std::nullopt;

const IdentifierNamingCheck::NamingStyle &Style = *NamingStyles[SK];
Comment on lines -1347 to -1350
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So dataflow couldn't handle checking for multiple optional values in one go? Seems like FP.

const auto &StyleOpt = NamingStyles[SK];
if (!StyleOpt)
return std::nullopt;

const IdentifierNamingCheck::NamingStyle &Style = *StyleOpt;
if (Style.IgnoredRegexp.isValid() && Style.IgnoredRegexp.match(Name))
return std::nullopt;

Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ static bool isQualificationConvertiblePointer(QualType From, QualType To,
"From pointer or array has no pointee or element!");
assert(ToPointeeOrElem && "To pointer or array has no pointee or element!");

if (!FromPointeeOrElem || !ToPointeeOrElem)
return false;

From = *FromPointeeOrElem;
To = *ToPointeeOrElem;
}
Expand Down