Skip to content

[HLSL] Add support for root constant generation from llvm IR. #127932

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 219 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
219 commits
Select commit Hold shift + click to select a range
526b34a
adding rootsignature to obj2yaml
Jan 13, 2025
e84a8e1
adding test
Jan 13, 2025
f25fd64
removing old test
Jan 13, 2025
16552f0
remove useless includes
Jan 13, 2025
a6eb4c0
addressing comments
Jan 14, 2025
7d080b3
updating test
Jan 14, 2025
504527b
removing useless header
Jan 15, 2025
2425672
fix formating
Jan 15, 2025
08c17bb
renaming test
Jan 15, 2025
395a536
addressing pr comments
Jan 16, 2025
f93dff9
adding str to ROOT_ELEMENT_FLAG
Jan 16, 2025
1c1edb8
formating
Jan 17, 2025
5bef775
refactoring to follow llvm standards
Jan 18, 2025
628545a
addressing comments
Jan 27, 2025
c5c2ab6
clean up
Jan 27, 2025
b9db72c
remove version
Jan 30, 2025
f4af043
fix pr
Jan 30, 2025
496b922
adding dxil-dis test
Jan 31, 2025
422578f
adding compatibility test
Jan 31, 2025
b1423eb
addressing test concerns
Feb 3, 2025
b6262b6
clean up
Feb 3, 2025
16d0e8e
addressing comments
Feb 4, 2025
0a9e468
adding fail test
Feb 4, 2025
8295031
adding comment
Feb 4, 2025
c8e1e38
adding few more tests
Feb 4, 2025
434b862
format
Feb 4, 2025
2bfc5ad
cleanup
Feb 5, 2025
479422d
adding metadata extraction
Jan 15, 2025
f61ee77
moving root signature to it's own pass
Jan 16, 2025
499d879
formating
Jan 16, 2025
c4af535
removing useless imports
Jan 16, 2025
819fa0d
fixing pr changes
Jan 16, 2025
d347a87
adding some asserts
Jan 16, 2025
d8824ed
format
Jan 16, 2025
25c0384
fixing assert
Jan 18, 2025
5eb0ad2
cleaning
Jan 27, 2025
559427d
clean up
Jan 29, 2025
8ca5b2a
addressing comments
Jan 30, 2025
d52cd2c
removing version
Jan 30, 2025
5930dcb
fix test
Jan 30, 2025
fc72988
addressing PR Comments
Jan 31, 2025
2d1ee0d
fix test
Feb 3, 2025
92a85fe
filtering root signatures not associated with entry function
Feb 4, 2025
979ee91
separating parsing and validation
Feb 4, 2025
d089674
improve error handling
Feb 6, 2025
980e7d9
clean up
Feb 6, 2025
04667f3
clean up
Feb 6, 2025
8ec40aa
formating
Feb 6, 2025
b0ac6be
addressing comments and fix tests
Feb 7, 2025
6a36503
formating
Feb 7, 2025
f7d2c12
addressing pr comments
Feb 10, 2025
d6c98ed
addressing PR comments
Feb 11, 2025
36746f5
addressing pr comments
Feb 11, 2025
b5208e8
removing copies from root signature use in dx container globals
Feb 11, 2025
1fd6568
adding more tests
Feb 12, 2025
cde4634
maybe fix test?
Feb 12, 2025
4410e7b
try fix format
Feb 12, 2025
cbdb114
removing test
Feb 12, 2025
667ee17
adding llvm unreachable and testing test
Feb 12, 2025
d0dae8b
stopping compilation if root signature error were emitted
Feb 12, 2025
b1b28f8
making sure Error tests fail
Feb 12, 2025
0efd8cc
adding root constants
Feb 12, 2025
11256d8
refactoring root signature analysis to return a map instead
Feb 12, 2025
3c5046e
addressing pr comments
Feb 12, 2025
5d4505c
clean up
Feb 12, 2025
3117530
addressing pr comments
Feb 13, 2025
0af845c
implementing find interface for RootSignatureAnalysisWrapper
Feb 13, 2025
bf49a3a
adding test for null function
Feb 13, 2025
78826a5
fix root signature test error
Feb 14, 2025
4e689e9
fix other functions are checked
Feb 14, 2025
b0d0180
adding missing continue
Feb 14, 2025
3c6894f
adding few more tests
Feb 14, 2025
08f6ddc
adding yaml2obj support
Feb 15, 2025
b232967
adding support for obj2yaml and initial tests
Feb 18, 2025
1026a8e
multiple parameters support and more testing
Feb 19, 2025
00175bf
clean up
Feb 19, 2025
9ed2adc
fixing formating
Feb 19, 2025
e8252ba
reapply rebase fix
Feb 19, 2025
4de5c29
clean up
Feb 20, 2025
fe13b61
addressing pr comments
Feb 22, 2025
767b7d0
first working version
Feb 22, 2025
8434dc2
formating
Feb 22, 2025
d391727
moving the offset logic to it's own class
Feb 24, 2025
68c7513
refactoring to remove use of map and string
Feb 24, 2025
23069ab
addressing comments
Feb 25, 2025
d14471b
using buffer_ostream
Feb 25, 2025
216341c
remove getsize
Feb 25, 2025
85f012c
clean up
Feb 25, 2025
1e2bcf5
clean up
Feb 25, 2025
0e277d9
clean up
Feb 25, 2025
5cd0044
clean up
Feb 25, 2025
7a7c34d
addressing pr comments
Feb 25, 2025
d3fafab
clean up
Feb 25, 2025
15d1a8c
Merge branch 'refactor/improve-offset-calculation' into users/joaosaf…
Feb 25, 2025
7485640
clean up
Feb 26, 2025
17abc82
moving initializer arround
Feb 26, 2025
4b177e2
addressing pr comments
Feb 26, 2025
ec1dd87
addressing changes
Feb 26, 2025
eb9d7d3
Merge branch 'main' into users/joaosaffran/127840
Feb 26, 2025
f2a4f04
fix test
Feb 26, 2025
7c4236c
refactoring to change representations in binary format
Mar 1, 2025
2894f96
addressing pr comments
Mar 2, 2025
9f96397
[RISCV] Adding missing P600 sched model test for RVV segmented loads/…
mshockwave Feb 26, 2025
1796b7d
[gn build] Port 8fb88f568011
llvmgnsyncbot Feb 26, 2025
0889558
[compiler-rt][rtsan] truncate/ftruncate interception. (#128904)
devnexen Feb 26, 2025
3c090ab
[memprof] std::move matchings (NFC) (#128933)
kazutakahirata Feb 26, 2025
33f53d8
[libc][bazel] Add targets for strfrom<float> (#128956)
michaelrj-google Feb 26, 2025
c2b3a2c
[libc][hdrgen] Allow to treat hdrgen Python code as a Python module. …
vonosmas Feb 26, 2025
cb5fe34
AMDGPU: Fix si-fix-sgpr-copies asserting on VReg_1 phi (#128903)
arsenm Feb 26, 2025
84a1494
Revert "[MLIR][LLVMIR] Import unregistered intrinsics via llvm.intrin…
bcardosolopes Feb 27, 2025
a062d66
[lldb-dap] Return an llvm::Error instead of calling exit directly (NF…
JDevlieghere Feb 27, 2025
25f1727
AMDGPU: Do not try to commute instruction with same input register (#…
arsenm Feb 27, 2025
56bb47f
AMDGPU: Fix overly conservative immediate operand check (#127563)
arsenm Feb 27, 2025
5850628
[clang][CodeGen] Additional fixes for #114062 (#128166)
AlexVlx Feb 27, 2025
eb0607e
[clang-format] Fix a bug that changes keyword `or` to an identifier (…
owenca Feb 27, 2025
6243145
[clang-format] Don't break before *const (#128817)
owenca Feb 27, 2025
7a2db57
[NFC] Fix Sanitizer breakage introduced in #128166 (#128990)
AlexVlx Feb 27, 2025
b6bdbdb
[ORC] De-duplicate some logic for handling MachO::dylib-based load co…
lhames Feb 26, 2025
3203f75
[ORC] Support adding LC_LOAD_WEAK_DYLIB commands to MachO JITDylib he…
lhames Feb 26, 2025
b770385
[ORC] Sink include into implementation file.
lhames Feb 27, 2025
3e4ca41
[X86][GlobalISel] Enable Trigonometric functions with libcall mapping…
JaydeepChauhan14 Feb 27, 2025
a974f2b
[lldb] Also show session history in fzf_history (#128986)
kastiglione Feb 27, 2025
84e1e22
LangRef: Clarify llvm.minnum and llvm.maxnum about sNaN and signed ze…
wzssyqa Feb 27, 2025
0bf4d4f
[mlir][Tosa] Add unreachable case for bad Extension type in TosaProfi…
enkerewpo Feb 27, 2025
fb5b3d3
[ctxprof] Override type of instrumentation if `-profile-context-root`…
mtrofin Feb 27, 2025
d23bb42
[RISCV] Add Xqccmp 0.1 Assembly Support (#128731)
lenary Feb 27, 2025
7914eea
[flang][cuda] Handle floats in atomiccas (#128970)
clementval Feb 27, 2025
bdac505
[CIR] Function type return type improvements (#128787)
dkolsen-pgi Feb 27, 2025
c5ffc52
[compiler-rt][sanitizer_common] copy_file_range syscall interception.…
devnexen Feb 27, 2025
3597b09
[msan] Generalize handlePairwiseShadowOrIntrinsic, and handle x86 pai…
thurstond Feb 27, 2025
16db97e
APFloat: Fix maxnum and minnum with sNaN (#112854)
wzssyqa Feb 27, 2025
c5cbfe2
[RISCV] Simplify createRISCVELFStreamer registration
MaskRay Feb 27, 2025
fc149a7
[AMDGPU] Verify SdwaSel value range (#128898)
frederik-h Feb 27, 2025
a8e52f8
[compiler-rt][sanitizer_common] fix copy_file_range test. (#129010)
devnexen Feb 27, 2025
bd4e612
[MLIR][NFC] Retire `let constructor` for Shape and MLProgram (#128869)
chelini Feb 27, 2025
bf9c36a
[AArch64] Simplify ELFStreamer and WinCOFFStreamer
MaskRay Feb 27, 2025
f0c5895
[RISCV] Correct RISCVTTIImpl::getIntImmCostInst for Zba (#128174)
futog Feb 27, 2025
8533a1d
[bazel] port 42526d240cc953963ea48bae0b4c2ab548e9d897
metaflow Feb 27, 2025
f112edd
[InstCombine] matchOrConcat - return Value* not Instruction* (#128921)
RKSimon Feb 27, 2025
0f786d6
Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo …
nikic Feb 27, 2025
5eaa64e
[DAG] replaceShuffleOfInsert - add support for shuffle_vector(scalar_…
RKSimon Feb 27, 2025
4977c78
[X86] combineINSERT_SUBVECTOR - use getBROADCAST_LOAD helper in inser…
RKSimon Feb 27, 2025
042217b
[lldb] Reimplement LineTable::FindLineEntryByAddress on top of lower_…
labath Feb 27, 2025
4818ffd
[AArch64] Add codesize test coverage. NFC
davemgreen Feb 27, 2025
ef2d116
[mlir][OpenMP] initialize (first)private variables before task exec (…
tblah Feb 27, 2025
0182090
[Docs] Fix typo in GetElementPtr.rst (#127393)
moar55 Feb 27, 2025
0404693
[mlir][OpenMP] Pack task private variables into a heap-allocated cont…
tblah Feb 27, 2025
9cb2f28
[LLVM][NVPTX] Add codegen support for tcgen05.{ld, st} instructions (…
schwarzschild-radius Feb 27, 2025
c02afe7
[X86] Add custom operation actions for f16: FABS, FNEG, and FCOPYSIGN…
StarOne01 Feb 27, 2025
32e2d62
[LV] Teach the loop vectorizer llvm.sincos is trivially vectorizable …
MacDue Feb 27, 2025
af3c826
[Bitcode] Avoid repeated hash lookups (NFC) (#128824)
kazutakahirata Feb 27, 2025
14409bf
[ARM] Avoid repeated hash lookups (NFC) (#128994)
kazutakahirata Feb 27, 2025
922443c
[AsmPrinter] Avoid repeated hash lookups (NFC) (#128995)
kazutakahirata Feb 27, 2025
6ad0879
[ExecutionEngine] Avoid repeated hash lookups (NFC) (#128997)
kazutakahirata Feb 27, 2025
2be9317
[IR] Avoid repeated hash lookups (NFC) (#128998)
kazutakahirata Feb 27, 2025
333dd5e
[SelectionDAG] Avoid repeated hash lookups (NFC) (#128999)
kazutakahirata Feb 27, 2025
3ce0280
[Support] Avoid repeated hash lookups (NFC) (#129000)
kazutakahirata Feb 27, 2025
a8f6de6
[X86] Merge insertsubvector(load(p0),load_subv(p0),hi) -> subvbroadca…
RKSimon Feb 27, 2025
ca8d8af
[lldb] Assorted improvements to the Pipe class (#128719)
labath Feb 27, 2025
76fa505
[MachineScheduler][AMDGPU] Allow scheduling of single-MI regions (#12…
lucas-rami Feb 27, 2025
bc4a15a
[NVPTX] Add Intrinsics for applypriority.* (#127989)
abhilash1910 Feb 27, 2025
6b87638
[NFC] [C++20] [Modules] Add a test for no transitive changes
ChuanqiXu9 Feb 27, 2025
1a2bc04
[LLVM][SVE] Add isel for bfloat based (de)interleave operations. (#12…
paulwalker-arm Feb 27, 2025
ee40442
[LoopVectorize] Use CodeSize as the cost kind for minsize (#124119)
john-brawn-arm Feb 27, 2025
2a1739b
[flang] Extend `omp loop` semantic checks for `reduction` (#128823)
ergawy Feb 27, 2025
7d11b30
[Clang][Sema] Add special handling of mfloat8 in initializer lists (#…
Lukacma Feb 27, 2025
4946bae
[clang-tidy] Fix performance-move-const-arg false negative in ternary…
RiverDave Feb 27, 2025
fbd2014
[CLANG]Update svget, svset, svcreate, svundef to have FP8 variants (#…
virginia-cangelosi Feb 27, 2025
3211a46
[clang-tidy] Add new check bugprone-unintended-char-ostream-output (#…
HerrCai0907 Feb 27, 2025
fea11a5
[AArch64] Do not split bfloat HFA args between regs and stack (#128909)
ostannard Feb 27, 2025
44a156b
[LV] Fix tests after 8150ab93f741.
fhahn Feb 27, 2025
82ac9aa
[lldb] Re-skip PipeTest on windows for now
labath Feb 27, 2025
eb27080
[libclc] Move sqrt to CLC library (#128748)
frasercrmck Feb 27, 2025
5ef7c95
[gn build] Port 56762b7ace05
llvmgnsyncbot Feb 27, 2025
74b2da9
[LoopVectorize][NFC] Fix formatting issue with a comment (#129033)
david-arm Feb 27, 2025
6fd5c69
AMDGPU: Factor agpr reg_sequence folding into a function (#129002)
arsenm Feb 27, 2025
d6d1401
AMDGPU: Add a mir variant of a regalloc failure test
arsenm Feb 27, 2025
74cb2a8
AMDGPU: Fix a test typo reading a partially undefined vector
arsenm Feb 27, 2025
23413be
AMDGPU: Fold bitcasts into readfirstlane, readlane, and permlane64 (#…
arsenm Feb 27, 2025
30e0079
[NFC][analyzer] Fix header comment in CreateCheckerManager.cpp (#129055)
NagyDonat Feb 27, 2025
44fd29b
[AArch64] Runtime-unroll small multi-exit loops on Apple Silicon. (#1…
fhahn Feb 27, 2025
17353c2
[SPIR-V] Support 2 more instructions from SPV_INTEL_long_composites (…
vmaksimo Feb 27, 2025
508fb73
[X86] getFauxShuffleMask - insert_subvector - skip undemanded subvect…
RKSimon Feb 27, 2025
bf611eb
[MergeFunc] Remove discardables function before writing alias or thun…
fhahn Feb 27, 2025
986725d
[DirectX] initialize registers properties by calling addRegisterClass…
farzonl Feb 27, 2025
29e1df1
[clang-tidy] Add a release note about unchecked-optional-access smart…
jvoung Feb 27, 2025
56a4c7c
[gn build] Port dc764f5c689f
llvmgnsyncbot Feb 27, 2025
f8f3fee
Add clang atomic control options and attribute (#114841)
yxsamliu Feb 27, 2025
bd3e191
[libclc] Move rsqrt to the CLC library (#129045)
frasercrmck Feb 27, 2025
3206f00
[AMDGPU][True16][MC] true16 for v_alignbit_b32 (#119409)
broxigarchen Feb 27, 2025
509fc62
[StackProtector] Add test for atomicrmw xchg (NFC)
nikic Feb 27, 2025
1b078ad
[StackProtector] Handle atomicrmw xchg in HasAddressTaken heuristic
nikic Feb 27, 2025
1006d8d
[clang] Ignore GCC 11 [[malloc(x)]] attribute
aloisklink Oct 2, 2023
7d77c73
[CodeGen][NVPTX] Add a TRI function get the Dwarf register number for…
topperc Feb 27, 2025
5216cd3
[MLIR][OpenMP]Add prescriptiveness-modifier support to granularity cl…
kaviya2510 Feb 27, 2025
eb510b6
[SLP]Add a test with incorrect bitwidth after minbitwidth analysis, NFC
alexey-bataev Feb 27, 2025
a5b6e03
[MemProf] Fix handling of recursive edges during func assignment (#12…
teresajohnson Feb 27, 2025
f6e2d6d
[SLP]Check for potential safety of the truncation for vectorized scal…
alexey-bataev Feb 27, 2025
662ba0d
[NFC][libc++] Guard against operator& hijacking. (#128351)
mordante Feb 27, 2025
c1a8c37
[Flang] Generate math.erfc op for non-precise erfc interinsic calls (…
jsjodin Feb 27, 2025
fdb09c1
[verify] Improve the error messages with multiple active prefixes (#1…
Maetveis Feb 27, 2025
63d1790
[AMDGPU][MC] Disassembler warning for v_cmpx instructions (#127925)
jwanggit86 Feb 27, 2025
9e22764
Reapply "[AMDGPU] Handle memcpy()-like ops in LowerBufferFatPointers …
krzysz00 Feb 27, 2025
5d81743
[NFC][analyzer] Simplify ownership of checker objects (#128887)
NagyDonat Feb 27, 2025
9ce7c00
[VPlan] Simplify BLEND %a, %b, NOT(%m) -> BLEND %b, %a, %m. (#128375)
fhahn Feb 27, 2025
70ae0a2
[OpenMP][OMPT][OMPD] Fix frame flags for OpenMP tool APIs (#114118)
jprotze Feb 27, 2025
c154a4b
AMDGPU: Use helper function for use/def chain walk (#129052)
arsenm Feb 27, 2025
ad83325
[libc][stdfix] Implement fixed point bitsfx functions in llvm libc (#…
krishna2803 Feb 27, 2025
70cc87e
[clang][deps] Propagate the entire service (#128959)
jansvoboda11 Feb 27, 2025
645c4f4
[MLIR][LLVMIR] Add support for atan2 intrinsics op (#127970)
FantasqueX Feb 27, 2025
1f0ab77
[SandboxVec][Scheduler] Enforce scheduling SchedBundle instrs back-to…
vporpo Feb 27, 2025
398b9c5
parsing root constant
Feb 19, 2025
18cd13c
add root constant support
Feb 20, 2025
e136489
clean up
Feb 20, 2025
f9ab918
change test
Feb 20, 2025
0e4a47e
first working version
Feb 22, 2025
4eec78d
merge and fix
Feb 26, 2025
17cee41
adding validation
Feb 28, 2025
79cdfff
fix rebase issues
Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
#include "UndelegatedConstructorCheck.h"
#include "UnhandledExceptionAtNewCheck.h"
#include "UnhandledSelfAssignmentCheck.h"
#include "UnintendedCharOstreamOutputCheck.h"
#include "UniquePtrArrayMismatchCheck.h"
#include "UnsafeFunctionsCheck.h"
#include "UnusedLocalNonTrivialVariableCheck.h"
Expand Down Expand Up @@ -147,6 +148,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-incorrect-enable-if");
CheckFactories.registerCheck<IncorrectEnableSharedFromThisCheck>(
"bugprone-incorrect-enable-shared-from-this");
CheckFactories.registerCheck<UnintendedCharOstreamOutputCheck>(
"bugprone-unintended-char-ostream-output");
CheckFactories.registerCheck<ReturnConstRefFromParameterCheck>(
"bugprone-return-const-ref-from-parameter");
CheckFactories.registerCheck<SwitchMissingDefaultCaseCheck>(
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ add_clang_library(clangTidyBugproneModule STATIC
InaccurateEraseCheck.cpp
IncorrectEnableIfCheck.cpp
IncorrectEnableSharedFromThisCheck.cpp
UnintendedCharOstreamOutputCheck.cpp
ReturnConstRefFromParameterCheck.cpp
SuspiciousStringviewDataUsageCheck.cpp
SwitchMissingDefaultCaseCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//===--- UnintendedCharOstreamOutputCheck.cpp - clang-tidy ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "UnintendedCharOstreamOutputCheck.h"
#include "clang/AST/Type.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Tooling/FixIt.h"

using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

namespace {

// check if the type is unsigned char or signed char
AST_MATCHER(Type, isNumericChar) {
return Node.isSpecificBuiltinType(BuiltinType::SChar) ||
Node.isSpecificBuiltinType(BuiltinType::UChar);
}

// check if the type is char
AST_MATCHER(Type, isChar) {
return Node.isSpecificBuiltinType(BuiltinType::Char_S) ||
Node.isSpecificBuiltinType(BuiltinType::Char_U);
}

} // namespace

UnintendedCharOstreamOutputCheck::UnintendedCharOstreamOutputCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context), CastTypeName(Options.get("CastTypeName")) {
}
void UnintendedCharOstreamOutputCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
if (CastTypeName.has_value())
Options.store(Opts, "CastTypeName", CastTypeName.value());
}

void UnintendedCharOstreamOutputCheck::registerMatchers(MatchFinder *Finder) {
auto BasicOstream =
cxxRecordDecl(hasName("::std::basic_ostream"),
// only basic_ostream<char, Traits> has overload operator<<
// with char / unsigned char / signed char
classTemplateSpecializationDecl(
hasTemplateArgument(0, refersToType(isChar()))));
Finder->addMatcher(
cxxOperatorCallExpr(
hasOverloadedOperatorName("<<"),
hasLHS(hasType(hasUnqualifiedDesugaredType(
recordType(hasDeclaration(cxxRecordDecl(
anyOf(BasicOstream, isDerivedFrom(BasicOstream)))))))),
hasRHS(hasType(hasUnqualifiedDesugaredType(isNumericChar()))))
.bind("x"),
this);
}

void UnintendedCharOstreamOutputCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *Call = Result.Nodes.getNodeAs<CXXOperatorCallExpr>("x");
const Expr *Value = Call->getArg(1);
const SourceRange SourceRange = Value->getSourceRange();

DiagnosticBuilder Builder =
diag(Call->getOperatorLoc(),
"%0 passed to 'operator<<' outputs as character instead of integer. "
"cast to 'unsigned int' to print numeric value or cast to 'char' to "
"print as character")
<< Value->getType() << SourceRange;

QualType T = Value->getType();
const Type *UnqualifiedDesugaredType = T->getUnqualifiedDesugaredType();

llvm::StringRef CastType = CastTypeName.value_or(
UnqualifiedDesugaredType->isSpecificBuiltinType(BuiltinType::SChar)
? "int"
: "unsigned int");

Builder << FixItHint::CreateReplacement(
SourceRange, ("static_cast<" + CastType + ">(" +
tooling::fixit::getText(*Value, *Result.Context) + ")")
.str());
}

} // namespace clang::tidy::bugprone
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===--- UnintendedCharOstreamOutputCheck.h - clang-tidy --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNINTENDEDCHAROSTREAMOUTPUTCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNINTENDEDCHAROSTREAMOUTPUTCHECK_H

#include "../ClangTidyCheck.h"
#include <optional>

namespace clang::tidy::bugprone {

/// Finds unintended character output from `unsigned char` and `signed char` to
/// an ostream.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/unintended-char-ostream-output.html
class UnintendedCharOstreamOutputCheck : public ClangTidyCheck {
public:
UnintendedCharOstreamOutputCheck(StringRef Name, ClangTidyContext *Context);
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
}

private:
const std::optional<StringRef> CastTypeName;
};

} // namespace clang::tidy::bugprone

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNINTENDEDCHAROSTREAMOUTPUTCHECK_H
14 changes: 10 additions & 4 deletions clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ void MoveConstArgCheck::registerMatchers(MatchFinder *Finder) {
unless(isInTemplateInstantiation()))
.bind("call-move");

// Match ternary expressions where either branch contains std::move
auto TernaryWithMoveMatcher =
conditionalOperator(hasDescendant(MoveCallMatcher));

Finder->addMatcher(
expr(anyOf(
castExpr(hasSourceExpression(MoveCallMatcher)),
Expand All @@ -58,13 +62,15 @@ void MoveConstArgCheck::registerMatchers(MatchFinder *Finder) {
qualType(rValueReferenceType()).bind("invocation-parm-type");
// Matches respective ParmVarDecl for a CallExpr or CXXConstructExpr.
auto ArgumentWithParamMatcher = forEachArgumentWithParam(
MoveCallMatcher, parmVarDecl(anyOf(hasType(ConstTypeParmMatcher),
hasType(RValueTypeParmMatcher)))
.bind("invocation-parm"));
anyOf(MoveCallMatcher, TernaryWithMoveMatcher),
parmVarDecl(
anyOf(hasType(ConstTypeParmMatcher), hasType(RValueTypeParmMatcher)))
.bind("invocation-parm"));
// Matches respective types of arguments for a CallExpr or CXXConstructExpr
// and it works on calls through function pointers as well.
auto ArgumentWithParamTypeMatcher = forEachArgumentWithParamType(
MoveCallMatcher, anyOf(ConstTypeParmMatcher, RValueTypeParmMatcher));
anyOf(MoveCallMatcher, TernaryWithMoveMatcher),
anyOf(ConstTypeParmMatcher, RValueTypeParmMatcher));

Finder->addMatcher(
invocation(anyOf(ArgumentWithParamMatcher, ArgumentWithParamTypeMatcher))
Expand Down
16 changes: 16 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ Improvements to clang-tidy
New checks
^^^^^^^^^^

- New :doc:`bugprone-unintended-char-ostream-output
<clang-tidy/checks/bugprone/unintended-char-ostream-output>` check.

Finds unintended character output from ``unsigned char`` and ``signed char`` to an
``ostream``.

New check aliases
^^^^^^^^^^^^^^^^^

Expand All @@ -102,6 +108,12 @@ Changes in existing checks
calls of ``std::string`` constructor with char pointer, start position and
length parameters.

- Improved :doc:`bugprone-unchecked-optional-access
<clang-tidy/checks/bugprone/unchecked-optional-access>` fixing false
positives from smart pointer accessors repeated in checking ``has_value``
and accessing ``value``. The option `IgnoreSmartPointerDereference` should
no longer be needed and will be removed.

- Improved :doc:`bugprone-unsafe-functions
<clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying
additional C++ member functions to match.
Expand All @@ -120,6 +132,10 @@ Changes in existing checks
tolerating fix-it breaking compilation when functions is used as pointers
to avoid matching usage of functions within the current compilation unit.

- Improved :doc:`performance-move-const-arg
<clang-tidy/checks/performance/move-const-arg>` check by fixing false negatives
on ternary operators calling ``std::move``.

Removed checks
^^^^^^^^^^^^^^

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ For example:
.. code-block:: c++

void f(Foo foo) {
if (foo.opt().has_value()) {
use(*foo.opt()); // unsafe: it is unclear whether `foo.opt()` has a value.
if (foo.take().has_value()) {
use(*foo.take()); // unsafe: it is unclear whether `foo.take()` has a value.
}
}

Expand All @@ -81,10 +81,11 @@ Exception: accessor methods

The check assumes *accessor* methods of a class are stable, with a heuristic to
determine which methods are accessors. Specifically, parameter-free ``const``
methods are treated as accessors. Note that this is not guaranteed to be safe
-- but, it is widely used (safely) in practice, and so we have chosen to treat
it as generally safe. Calls to non ``const`` methods are assumed to modify
the state of the object and affect the stability of earlier accessor calls.
methods and smart pointer-like APIs (non ``const`` overloads of ``*`` when
there is a parallel ``const`` overload) are treated as accessors. Note that
this is not guaranteed to be safe -- but, it is widely used (safely) in
practice. Calls to non ``const`` methods are assumed to modify the state of
the object and affect the stability of earlier accessor calls.

Rely on invariants of uncommon APIs
-----------------------------------
Expand Down Expand Up @@ -191,14 +192,15 @@ paths that lead to an access. For example:
Stabilize function results
~~~~~~~~~~~~~~~~~~~~~~~~~~

Since function results are not assumed to be stable across calls, it is best to
store the result of the function call in a local variable and use that variable
to access the value. For example:
Function results are not assumed to be stable across calls, except for
const accessor methods. For more complex accessors (non-const, or depend on
multiple params) it is best to store the result of the function call in a
local variable and use that variable to access the value. For example:

.. code-block:: c++

void f(Foo foo) {
if (const auto& foo_opt = foo.opt(); foo_opt.has_value()) {
if (const auto& foo_opt = foo.take(); foo_opt.has_value()) {
use(*foo_opt);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.. title:: clang-tidy - bugprone-unintended-char-ostream-output

bugprone-unintended-char-ostream-output
=======================================

Finds unintended character output from ``unsigned char`` and ``signed char`` to an
``ostream``.

Normally, when ``unsigned char (uint8_t)`` or ``signed char (int8_t)`` is used, it
is more likely a number than a character. However, when it is passed directly to
``std::ostream``'s ``operator<<``, the result is the character output instead
of the numeric value. This often contradicts the developer's intent to print
integer values.

.. code-block:: c++

uint8_t v = 65;
std::cout << v; // output 'A' instead of '65'

The check will suggest casting the value to an appropriate type to indicate the
intent, by default, it will cast to ``unsigned int`` for ``unsigned char`` and
``int`` for ``signed char``.

.. code-block:: c++

std::cout << static_cast<unsigned int>(v); // when v is unsigned char
std::cout << static_cast<int>(v); // when v is signed char

To avoid lengthy cast statements, add prefix ``+`` to the variable can also
suppress warnings because unary expression will promote the value to an ``int``.

.. code-block:: c++

std::cout << +v;

Or cast to char to explicitly indicate that output should be a character.

.. code-block:: c++

std::cout << static_cast<char>(v);

.. option:: CastTypeName

When `CastTypeName` is specified, the fix-it will use `CastTypeName` as the
cast target type. Otherwise, fix-it will automatically infer the type.
1 change: 1 addition & 0 deletions clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ Clang-Tidy Checks
:doc:`bugprone-undelegated-constructor <bugprone/undelegated-constructor>`,
:doc:`bugprone-unhandled-exception-at-new <bugprone/unhandled-exception-at-new>`,
:doc:`bugprone-unhandled-self-assignment <bugprone/unhandled-self-assignment>`,
:doc:`bugprone-unintended-char-ostream-output <bugprone/unintended-char-ostream-output>`, "Yes"
:doc:`bugprone-unique-ptr-array-mismatch <bugprone/unique-ptr-array-mismatch>`, "Yes"
:doc:`bugprone-unsafe-functions <bugprone/unsafe-functions>`,
:doc:`bugprone-unused-local-non-trivial-variable <bugprone/unused-local-non-trivial-variable>`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// RUN: %check_clang_tidy %s bugprone-unintended-char-ostream-output %t -- \
// RUN: -config="{CheckOptions: \
// RUN: {bugprone-unintended-char-ostream-output.CastTypeName: "uint8_t"}}"

namespace std {

template <class _CharT, class _Traits = void> class basic_ostream {
public:
basic_ostream &operator<<(int);
basic_ostream &operator<<(unsigned int);
};

template <class CharT, class Traits>
basic_ostream<CharT, Traits> &operator<<(basic_ostream<CharT, Traits> &, CharT);
template <class CharT, class Traits>
basic_ostream<CharT, Traits> &operator<<(basic_ostream<CharT, Traits> &, char);
template <class _Traits>
basic_ostream<char, _Traits> &operator<<(basic_ostream<char, _Traits> &, char);
template <class _Traits>
basic_ostream<char, _Traits> &operator<<(basic_ostream<char, _Traits> &,
signed char);
template <class _Traits>
basic_ostream<char, _Traits> &operator<<(basic_ostream<char, _Traits> &,
unsigned char);

using ostream = basic_ostream<char>;

} // namespace std

class A : public std::ostream {};

void origin_ostream(std::ostream &os) {
unsigned char unsigned_value = 9;
os << unsigned_value;
// CHECK-MESSAGES: [[@LINE-1]]:6: warning: 'unsigned char' passed to 'operator<<' outputs as character instead of integer
// CHECK-FIXES: os << static_cast<uint8_t>(unsigned_value);

signed char signed_value = 9;
os << signed_value;
// CHECK-MESSAGES: [[@LINE-1]]:6: warning: 'signed char' passed to 'operator<<' outputs as character instead of integer
// CHECK-FIXES: os << static_cast<uint8_t>(signed_value);

char char_value = 9;
os << char_value;
}
Loading