[PATCH] D158948: [clang][ASTImporter] Add import of type-related nodes

2023-08-29 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:1758
+  *ToAttrLocOrErr);
+}
+

At cases like this (many imported values) `importChecked` can be used, like at 
`VisitDependentSizedArrayType`.



Comment at: clang/unittests/AST/ASTImporterObjCTest.cpp:100
+  FirstDeclMatcher().match(ToInterfaceDecl, Pattern);
+  ASSERT_TRUE(ToTypeParamDeclImported);
+  ASSERT_TRUE(ToTypeParamDeclMatched);

This single assert can be sufficient for this test because the ToTU was empty 
before import, it is not expected that more than one instance will be created. 
Better is to check for example if `getTypeForDecl` is correctly imported.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158948/new/

https://reviews.llvm.org/D158948

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157684: [clang][ASTImporter] Repeated friend templates are partially imported

2023-08-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:4087
+
+  if (TypeSourceInfo *TSI = FD1->getFriendType())
+return Importer.IsStructurallyEquivalent(

This can be `const`?



Comment at: clang/lib/AST/ASTImporter.cpp:4105
 
-  T TypeOrDecl = GetCanTypeOrDecl(FD);
-
-  for (const FriendDecl *FoundFriend : RD->friends()) {
+  for (FriendDecl *FoundFriend : RD->friends()) {
 if (FoundFriend == FD) {

It is better if this is `const`.



Comment at: clang/lib/AST/ASTImporter.cpp:4130
   SmallVector ImportedEquivalentFriends;
-
-  while (ImportedFriend) {
-bool Match = false;
-if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) {
-  Match =
-  IsStructuralMatch(D->getFriendDecl(), 
ImportedFriend->getFriendDecl(),
-/*Complain=*/false);
-} else if (D->getFriendType() && ImportedFriend->getFriendType()) {
-  Match = Importer.IsStructurallyEquivalent(
-  D->getFriendType()->getType(),
-  ImportedFriend->getFriendType()->getType(), /*Complain=*/false);
-}
-if (Match)
+  for (auto *ImportedFriend : RD->friends())
+if (IsEquivalentFriend(Importer, D, ImportedFriend))

`auto` should be replaced here


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157684/new/

https://reviews.llvm.org/D157684

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157684: [clang][ASTImporter] Repeated friend templates are partially imported

2023-08-22 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:4072
+
+  if (auto *TSI = FD1->getFriendType())
+return Importer.IsStructurallyEquivalent(

According to the coding rules `auto` should not be used here.



Comment at: clang/lib/AST/ASTImporter.cpp:4079
+  Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
+  /* StrictTypeSpelling = */ false, /* Complain = */ false);
+  return Ctx.IsEquivalent(FD1, FD2);

This is a comparison in the same AST context ("From" side). 
`Importer.getNonEquivalentDecls()` returns a cache that is used at compares 
between "From" and "To" context. This is not valid for this use, you can simply 
pass an empty map instead, or add a new member that is used (only) here. 
`getStructuralEquivalenceKind(Importer)` is not needed for this compare, it can 
be always "Default".



Comment at: clang/lib/AST/ASTImporter.cpp:4089
 
-  T TypeOrDecl = GetCanTypeOrDecl(FD);
-
-  for (const FriendDecl *FoundFriend : RD->friends()) {
+  for (auto *FoundFriend : RD->friends()) {
 if (FoundFriend == FD) {

`auto` is not good here too.



Comment at: clang/lib/AST/ASTImporter.cpp:4114
   SmallVector ImportedEquivalentFriends;
-
-  while (ImportedFriend) {
-bool Match = false;
-if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) {
-  Match =
-  IsStructuralMatch(D->getFriendDecl(), 
ImportedFriend->getFriendDecl(),
-/*Complain=*/false);
-} else if (D->getFriendType() && ImportedFriend->getFriendType()) {
-  Match = Importer.IsStructurallyEquivalent(
-  D->getFriendType()->getType(),
-  ImportedFriend->getFriendType()->getType(), /*Complain=*/false);
-}
-if (Match)
+  for (auto *ImportedFriend : RD->friends())
+if (IsEquivalentFriend(Importer, D, ImportedFriend))

`auto` should not be used here, this loop could be replaced by some generic 
"algorithm" function call (`llvm::copy_if`).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157684/new/

https://reviews.llvm.org/D157684

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158156: [analyzer] Add C++ array delete checker

2023-08-21 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

I found that this concept of "fake" checkers (that change only options of a 
common checker instance) has more problems (checker dependencies, callback 
order, separation of "modeling" and bug report generation independently), it is 
better to avoid this. It is really the same as having options of a single 
checker (separate checkers are not the same as options of a checker), otherwise 
a common base class or common code module is a better option.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158156/new/

https://reviews.llvm.org/D158156

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-21 Thread Balázs Kéri via Phabricator via cfe-commits
balazske accepted this revision.
balazske added a comment.
This revision is now accepted and ready to land.

My concern was related to nested namespaces or nested classes with friend 
declarations that are equivalent and differ only in the nesting level. It may 
be possible to construct code where a declaration at an inner (nested) level is 
found to be equivalent with a similar looking class at an outer level. But I 
now do not have time to look for an example to test it, and I am not fully 
familiar with exact rules of friend declarations, so I accept this fix.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156693/new/

https://reviews.llvm.org/D156693

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156461: [clang][ASTImporter] Merge implicit ctors with definition

2023-08-18 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

After import we get a new AST that looks like this:

  |-CXXConstructorDecl 0x556e6a172d58  col:16 implicit used constexpr A 
'void (A &&)' inline default trivial noexcept-unevaluated 0x556e6a172d58
  | `-ParmVarDecl 0x556e6a172e78  col:16 'A &&'
  `-CXXConstructorDecl 0x556e6a1ac250 prev 0x556e6a172d58  
col:16 implicit used constexpr A 'void (A &&) noexcept' inline default trivial
|-ParmVarDecl 0x556e6a1730e0  col:16 used 'A &&'
|-CXXCtorInitializer Field 0x556e6a172850 'm' 'int'
| `-ImplicitCastExpr 0x556e6a1ac3a0  'int' 
|   `-MemberExpr 0x556e6a1ac370  'int' xvalue .m 0x556e6a172850
| `-CXXStaticCastExpr 0x556e6a1ac340  'A':'A' xvalue 
static_cast 
|   `-DeclRefExpr 0x556e6a1ac308  'A':'A' lvalue ParmVar 
0x556e6a1730e0 '' 'A &&'
`-CompoundStmt 0x556e6a1ac3e0 

It contains a re-declaration of the (implicit) move constructor, but I do not 
know if this AST causes problems practically. To avoid this situation we must 
change the existing To AST in the import process to add the definition of the 
move constructor (to the existing which has no definition). Theoretically this 
may be possible, but it is different from how the `ASTImporter` currently 
works, now every imported function declaration is created and linked to the 
existing ones. (But there are already some values that are updated in the To 
AST.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156461/new/

https://reviews.llvm.org/D156461

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158145: [clang] Update NumFunctionDeclBits for FunctionDeclBitfields

2023-08-17 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/unittests/AST/DeclTest.cpp:368
+  ASTContext  = AST->getASTContext();
+  Ctx.getTranslationUnitDecl()->dump();
+

This dump is not needed?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158145/new/

https://reviews.llvm.org/D158145

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-15 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/unittests/AST/StructuralEquivalenceTest.cpp:1716
+   IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
+  auto t = makeDecls(
+  R"(

The convention is to start variable names with uppercase, for example "Decls".


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156693/new/

https://reviews.llvm.org/D156693

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157691: [ASTImporter] Remove extranous FunctionTemplateDecl introduced by templated friend

2023-08-15 Thread Balázs Kéri via Phabricator via cfe-commits
balazske accepted this revision.
balazske added a comment.
This revision is now accepted and ready to land.

Additionally, use the "[clang][ASTImporter]" tags at commit message.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157691/new/

https://reviews.llvm.org/D157691

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-15 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/unittests/AST/StructuralEquivalenceTest.cpp:1709
+  classTemplateDecl(hasName("A")));
+  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_TRUE(testStructuralMatch(t, true));

The intent was to have `EXPECT_FALSE` without ignore depth, and the next test 
would be not needed. If it does not work with this code a different code can be 
found. The depth of the (unnamed) template parameter is really different in 
these cases too, but it is probably not detected by structural equivalence. 
Maybe `template` or `template` is needed. But to document 
this behavior the current test can be added too, with name 
`IgnoreTemplateParmDepthAtTemplateTypeParmDecl`, and the new one with name 
`IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156693/new/

https://reviews.llvm.org/D156693

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157691: [ASTImporter] Remove extranous FunctionTemplateDecl introduced by templated friend

2023-08-15 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

When committing this patch, the commit message should not contain the whole AST 
and crash dump (phabricator takes the "summary" text), this looks too much in a 
commit message. One AST dump from the wrong To AST is enough.




Comment at: clang/test/Import/templated-friend/test.cpp:5
+  A a;
+}

These test files are really not needed. The same AST import is performed in the 
unit test.



Comment at: clang/unittests/AST/ASTImporterTest.cpp:5644
+)",
+   Lang_CXX03, "", Lang_CXX03, "X");
+

This formatting looks not correct.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157691/new/

https://reviews.llvm.org/D157691

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-15 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/unittests/AST/StructuralEquivalenceTest.cpp:1697
+TEST_F(StructuralEquivalenceTemplateTest,
+   ClassTemplateEquivalentFriendClassTemplate) {
+  auto t = makeDecls(

   IgnoreTemplateParmDepth) {



Comment at: clang/unittests/AST/StructuralEquivalenceTest.cpp:1732
+  EXPECT_FALSE(testStructuralMatch(Friend->getFriendDecl(), get<1>(t)));
+  EXPECT_TRUE(testStructuralMatch(Friend->getFriendDecl(), get<1>(t), true));
+}

It should work with more simple code like:
```
makeDecls(
  R"(
template struct A;
  )",
  R"(
template struct S {
  template friend struct A;
};
  )",
  Lang_CXX03, classTemplateDecl(hasName("A")), classTemplateDecl(hasName("A"))
);
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156693/new/

https://reviews.llvm.org/D156693

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157691: [ASTImporter] Remove extranous FunctionTemplateDecl introduced by templated friend

2023-08-14 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

It is better to add a test to ASTImporterTests.cpp with the same code, and 
check the properties of DeclContext and LexicalDeclContext in the From and To 
AST (should be the same in "From" and "To" side).




Comment at: clang/lib/AST/ASTImporter.cpp:6451
+  if (D->getFriendObjectKind() == Decl::FOK_None)
+LexicalDC->addDeclInternal(ToFunc);
 

`addDeclToContexts(D, ToFunction)` should be better


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157691/new/

https://reviews.llvm.org/D157691

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-14 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

A simple test should be added to StructuralEquivalenceTest.cpp too to check if 
ignore (and not ignore) depth works.

I think this solution is not always correct, but is still an improvement.




Comment at: clang/include/clang/AST/ASTStructuralEquivalence.h:80
+  bool Complain = true, bool ErrorOnTagTypeMismatch = false,
+  bool IgnoreDepth = false)
   : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),

  bool IgnoreTemplateParmDepth = false)



Comment at: clang/lib/AST/ASTImporter.cpp:511
+bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true,
+   bool IgnoreDepth = true);
 ExpectedDecl VisitDecl(Decl *D);

This should be `false` to have the original behavior if not specified.



Comment at: clang/lib/AST/ASTImporter.cpp:5831
+FoundTemplate->getFriendObjectKind() != Decl::FOK_None &&
+!D->specializations().empty();
+if (IsStructuralMatch(D, FoundTemplate, true, IgnoreDepth)) {

Probably add `IsFriendTemplate`?



Comment at: clang/unittests/AST/ASTImporterTest.cpp:4258
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));
+  auto *ToA = Import(FromA, Lang_CXX11);

Probably add `hasDefinition()` to the matcher.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156693/new/

https://reviews.llvm.org/D156693

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156461: [clang][ASTImporter] Merge implicit ctors with definition

2023-08-14 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

It looks not good to remove an invalid node from the DeclContext that otherwise 
remains in the AST. I checked the problem and found that the existing move 
constructor (originally in the To AST which had no definition) gets a 
`getNumCtorInitializers` value of 1 but the `init_begin` returns 0. This causes 
crash even when dumping it. I did not find the cause of this situation (the 
first time at line 3822 it is already changed, and `ASTImporter` has this 
single position to change the value). Normally what should happen is that a new 
move constructor is imported (with a definition) and linked after the existing 
one (and the existing is not modified). We get an AST that does not occur after 
a normal compile, I do not know if this causes problems or if this is the real 
reason for this patch. What should be done is find the existing constructor and 
update it with the definition and return it from the import. This can be done 
with any type of constructor.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156461/new/

https://reviews.llvm.org/D156461

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-08-10 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

About the questions:

- How many issues does it raise? Would we flood the user?

I did not experience that the checker produces many warnings. Any warning from 
this checker is connected to a function call of a standard API, and the number 
of such calls is usually not high. Typically one 
problem which the checker reports can occur often in a specific program, for 
example the `fileno` case (fileno returns -1 at failure, often this failure is 
not handled and value -1 is used as a file number). 
This should not be a case of hundreds of warnings.

- How "interesting" those issues are? Do they have *actual* value for the user? 
(Not only niece edge-cases, that is fancy to know about, but actual users would 
genuinely commit such mistakes)

If the coder cares about all edge-cases of API calls, these are real and 
important issues. More often most of the results are just cases of ignored 
errors that are very rare, the programmer probably intentionally did not handle 
these because it is not worth for a such rare situation. From security point of 
view these cases can be used to find places where it is possible to make an API 
call (which normally "never" fails) intentionally fail and produce unexpected 
behavior of the program. So for an average application many results are not 
very important, for stability and security critical code the results can be 
more important.

- How long those bug-paths are in practice? I'd argue, the longer they are, 
usually the less actionable they are for the user. Less actionable reports are 
also less valuable, or even harmful.

The bug path can be long, often only the very last part is important, but 
sometimes not.

- In general, how understandable these reports are? Do we have all the 
interesting "notes" or "events" on the path?

These should be not more difficult to understand than a division by zero, only 
with a function call instead of division.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-08-08 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

I have checked the results on some projects 
(memcached,tmux,curl,twin,vim,openssl,sqlite,ffmpeg,postgres,xerces,bitcoin).

These results are more interesting, some look correct, some probably not:
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=curl_curl-7_66_0_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=2243964=d4a4bda38c5a6fdaabe2c1867158b106=%2atftpd.c
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=ffmpeg_n4.3.1_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=908f965d980d60292af95db0fa10cd5f=2252082=%2av4l2_buffers.c
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=postgres_REL_13_0_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=914e79646cb0de40dab434ba24c8c23c=2259781=%2adsm_impl.c
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=postgres_REL_13_0_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=58d8278be40f99597b44323d2574c053=2259789=%2asyslogger.c
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=postgres_REL_13_0_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=1928ba718d9742340937d425ec3978c6=2260011=%2apg_backup_custom.c
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=bitcoin_v0.20.1_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=6ad3a20f18f2850293b4cdd867e404e2=2266103=%2aenv_posix.cc

This is more questionable:
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=twin_v0.8.1_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=50a98122502701302b7b75a6a56342e8=2244071=%2ashm.c

Correct but interesting, the note about failure of `ftell` is shown:
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=xerces_v3.2.3_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions=4ab640064066880ac7031727869c92f4=2260149=%2aThreadTest.cpp

I did not find results that are obvious false positive.
Many results are the case when `fileno` returns -1 and this value is used 
without check. The checker generates a note about failure of `fileno`. For 
example at these results:
https://codechecker-demo.eastus.cloudapp.azure.com/Default/reports?run=postgres_REL_13_0_stdclibraryfunctions_alpha=on=New=unix.StdCLibraryFunctions
(There are cases when `fileno(stderr)` is assumed to fail. This case can be 
eliminated if the `StreamChecker` is enabled, after an improvement of the 
checker. But for this `StreamChecker` must run before 
`StdCLibraryFunctionsChecker`?)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156693: [clang][ASTImporter]Skip check friend template depth

2023-08-08 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

This fix can cause problems because the depth comparison is omitted all times. 
It would be better to omit depth check if the imported template is a friend, 
and has a `ClassTemplateSpecializationDecl` as context. Probably even then it 
is possible to construct cases where the checked template has references to 
other templates with different "depth" which should not omitted in the check. 
But I have no idea of a better solution, only to pass a `ClassTemplateDecl` or 
`ClassTemplateSpecializationDecl` to `StructuralEquivalenceContext` and omit 
the depth check only at this object.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156693/new/

https://reviews.llvm.org/D156693

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-08-08 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

This checker was originally in the "unix" package. I agree that this is not 
exact and `core` can be better, the checked functions should be available in 
any default C library on UNIX, OSX, Windows or other platforms too, even the 
POSIX ones at least in some cases.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-08-07 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 54.
balazske added a comment.
Herald added a subscriber: wangpc.

Using the latest version of the checker.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

Files:
  clang/docs/ReleaseNotes.rst
  clang/docs/analyzer/checkers.rst
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/test/Analysis/PR49642.c
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/analyzer-enabled-checkers.c
  clang/test/Analysis/conversion.c
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/errno-stdlibraryfunctions.c
  clang/test/Analysis/std-c-library-functions-POSIX-lookup.c
  clang/test/Analysis/std-c-library-functions-POSIX-socket-sockaddr.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
  clang/test/Analysis/std-c-library-functions-arg-cstring-dependency.c
  clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/Analysis/std-c-library-functions-eof.c
  clang/test/Analysis/std-c-library-functions-inlined.c
  clang/test/Analysis/std-c-library-functions-lookup.c
  clang/test/Analysis/std-c-library-functions-lookup.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/std-c-library-functions-restrict.c
  clang/test/Analysis/std-c-library-functions-restrict.cpp
  clang/test/Analysis/std-c-library-functions-vs-stream-checker.c
  clang/test/Analysis/std-c-library-functions.c
  clang/test/Analysis/std-c-library-functions.cpp
  clang/test/Analysis/std-c-library-posix-crash.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-errno.c
  clang/test/Analysis/stream-noopen.c
  clang/test/Analysis/stream-note.c
  clang/test/Analysis/stream-stdlibraryfunctionargs.c
  clang/test/Analysis/weak-dependencies.c

Index: clang/test/Analysis/weak-dependencies.c
===
--- clang/test/Analysis/weak-dependencies.c
+++ clang/test/Analysis/weak-dependencies.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 %s -verify \
-// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
+// RUN:   -analyzer-checker=unix.StdCLibraryFunctions \
 // RUN:   -analyzer-checker=core
 
 typedef __typeof(sizeof(int)) size_t;
Index: clang/test/Analysis/stream-stdlibraryfunctionargs.c
===
--- clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -1,11 +1,11 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
+// RUN:   -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
 
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdfunc,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdfunc,any %s
 
 #include "Inputs/system-header-simulator.h"
 
Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -analyzer-output text \
 // RUN:   -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions -analyzer-output text \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=expected,stdargs %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,unix.StdCLibraryFunctions -analyzer-output text \
+// RUN:   -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -verify=expected,stdargs %s
 
 #include "Inputs/system-header-simulator.h"
 
Index: 

[PATCH] D157238: [clang][ASTImporter] Add import of 'DependentSizedExtVectorType'

2023-08-07 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

In D157238#4565260 , @danix800 wrote:

> In D157238#4565051 , @balazske 
> wrote:
>
>> `ASTImporter` part looks good, I did not check the generated documentation 
>> for correctness.
>
> Matcher part will be committed in https://reviews.llvm.org/D157237, these 
> code is added here only to support this revision.

It is possible to add D157237  as parent 
revision (and upload code here without changes in D157237 
). It is more safe to have the exact same 
code in the review that will be committed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157238/new/

https://reviews.llvm.org/D157238

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157238: [clang][ASTImporter] Add import of 'DependentSizedExtVectorType'

2023-08-07 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

`ASTImporter` part looks good, I did not check the generated documentation for 
correctness.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157238/new/

https://reviews.llvm.org/D157238

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155715: [clang][analyzer] Improve StdCLibraryFunctions socket send/recv functions.

2023-08-07 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG52ac71f92d38: [clang][analyzer] Improve StdCLibraryFunctions 
socket send/recv functions. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155715/new/

https://reviews.llvm.org/D155715

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c

Index: clang/test/Analysis/std-c-library-functions-POSIX.c
===
--- clang/test/Analysis/std-c-library-functions-POSIX.c
+++ clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -141,6 +141,8 @@
 
 #include "Inputs/std-c-library-functions-POSIX.h"
 
+void clang_analyzer_eval(int);
+
 void test_open(void) {
   open(0, 0); // \
   // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
@@ -150,3 +152,56 @@
   open(0, 0, 0); // \
   // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
 }
+
+void test_recvfrom(int socket, void *restrict buffer, size_t length, int flags,
+   struct sockaddr *restrict address,
+   socklen_t *restrict address_len) {
+  ssize_t Ret = recvfrom(socket, buffer, length, flags, address, address_len);
+  if (Ret == 0)
+clang_analyzer_eval(length == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(length > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_sendto(int socket, const void *message, size_t length, int flags,
+ const struct sockaddr *dest_addr, socklen_t dest_len) {
+  ssize_t Ret = sendto(socket, message, length, flags, dest_addr, dest_len);
+  if (Ret == 0)
+clang_analyzer_eval(length == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(length > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_recv(int sockfd, void *buf, size_t len, int flags) {
+  ssize_t Ret = recv(sockfd, buf, len, flags);
+  if (Ret == 0)
+clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(len > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_send(int sockfd, void *buf, size_t len, int flags) {
+  ssize_t Ret = send(sockfd, buf, len, flags);
+  if (Ret == 0)
+clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(len > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_recvmsg(int sockfd, struct msghdr *msg, int flags) {
+  ssize_t Ret = recvmsg(sockfd, msg, flags);
+  clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}}
+}
+
+void test_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
+  ssize_t Ret = sendmsg(sockfd, msg, flags);
+  clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}}
+}
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3096,7 +3096,10 @@
 auto Recvfrom =
 Summary(NoEvalCall)
 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
-   ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
+   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
+  ErrnoMustNotBeChecked, GenericSuccessMsg)
+.Case({ReturnValueCondition(WithinRange, SingleValue(0)),
+   ArgumentCondition(2, WithinRange, SingleValue(0))},
   ErrnoMustNotBeChecked, GenericSuccessMsg)
 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
 .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
@@ -3123,7 +3126,10 @@
 auto Sendto =
 Summary(NoEvalCall)
 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
-   ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
+   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
+  ErrnoMustNotBeChecked, GenericSuccessMsg)
+.Case({ReturnValueCondition(WithinRange, SingleValue(0)),
+   ArgumentCondition(2, WithinRange, SingleValue(0))},
   ErrnoMustNotBeChecked, GenericSuccessMsg)
 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
 .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
@@ -3161,7 +3167,10 @@
   RetType{Ssize_tTy}),
 Summary(NoEvalCall)
   

[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-04 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

The summary tells nothing about what is the real problem to fix here. In the 
lit test I see that an error message is displayed, this causes the test 
failure. The problem is that the structural equivalence check is not good for 
this special case. The imported AST contains a class template specialization 
for `A`, in this specialization the friend class template `A` has a previous 
decl that points to the original friend class template that is in a 
`ClassTemplateDecl`. In the specialization the "depth" of template arguments is 
0, but in the original template it is 1 (the "to" code at import contains only 
the "original template", no specialization). This difference in the "depth" 
causes the type mismatch when the specialization is imported.
AST dump of this code can show the problem:

  template
  class A;
  
  template
  class A {
  public:
template
friend class A;
  
A(T x):x(x){}

  private:
T x;
  };
  
  A a1(0);

It is really interesting that at friend templates the depth is 1 but friend 
declarations point to objects outside the class, so really the depth should not 
increase in a friend template from this point of view. But this is an AST issue.




Comment at: clang/lib/AST/ASTImporter.cpp:5829
+!IsStructuralMatch(D, FoundTemplate, false))
+  continue;
 if (IsStructuralMatch(D, FoundTemplate)) {

It is not good to use `ParentMap` in the AST importer because it does AST 
traversal, even worse if this is done on the To context where the AST is 
modified and may be in incomplete state.
This way of fix is probably not good for a case when there is a real structural 
in-equivalence, this would be not detected. And the current solution skips this 
`FoundDecl` but (at least in the used test code) this should be found, not 
skipped. (But we can create code where the skip is correct, if there is a real 
structural in-equivalence.)




Comment at: clang/unittests/AST/ASTImporterTest.cpp:4218
+  R"(
+namespace __1{
+

I think the `namespace __1` is not important for reproduction of this problem.



Comment at: clang/unittests/AST/ASTImporterTest.cpp:4234
+  int j=1/i;
+  (void)j;
+}

Functions `foo`, `bar`, `main` are not required. It is only important to have a 
variable of type `A` like `A a1(0);` in the imported code at getTuDecl.



Comment at: clang/unittests/AST/ASTImporterTest.cpp:4247
+  }
+  )",
+  Lang_CXX11);

The coding format should be aligned to the format of other test codes in this 
file, and this is normally same as the clang format guidelines (automatic 
reformatting does not work in the test code).



Comment at: clang/unittests/AST/ASTImporterTest.cpp:4284
+  Lang_CXX11, "input1.cc");
+  auto *Definition = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));

`Definition` is misleading because this is not the definition, it matches the 
first declaration of `A` in the AST. Better name is like `FromA` like in the 
other tests, or FromXxx.



Comment at: clang/unittests/AST/ASTImporterTest.cpp:4286
+  FromTU, classTemplateDecl(hasName("A")));
+  auto *Template = Import(Definition, Lang_CXX11);
+  EXPECT_TRUE(Template);

The imported name can be `ToA` or ToXxx or ImportedXxx, this makes real 
distinction between the from and to objects.



Comment at: clang/unittests/AST/ASTImporterTest.cpp:4288
+  EXPECT_TRUE(Template);
+  auto *TemplateClass = cast(Template);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),

This cast is not needed, type of `Template` is already `ClassTemplateDecl*`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156693/new/

https://reviews.llvm.org/D156693

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156201: [ASTImporter] Fix corrupted RecordLayout introduced by circular referenced fields

2023-08-01 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a reviewer: aaron.ballman.
balazske added a comment.

The fix looks good, only a person with AST competence should have a look at it 
because a change in `Expr.h`.




Comment at: clang/unittests/AST/ASTImporterTest.cpp:8033
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ImportCirularRefFieldsWithoutCorruptedRecordLayoutCacheTest) {
+  // Import sequence: A => A.b => B => B.f() => ... => UnaryOperator(&) => ...

A small thing, `ImportCirularRefFieldsWithoutCorruptedRecordLayoutCache` (no 
`Test` ending) is the usual naming for these tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156201/new/

https://reviews.llvm.org/D156201

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155661: [clang][ASTImporter] Fix friend class template import within dependent context

2023-08-01 Thread Balázs Kéri via Phabricator via cfe-commits
balazske accepted this revision.
balazske added a comment.
This revision is now accepted and ready to land.

The fix looks OK, but the test could be improved and cleaned up (for example 
`FromClass` is the same as `FromD` in the test, and DeclContext is not checked, 
can be done like in the test `UndeclaredFriendClassShouldNotBeVisible` but the 
AST is different). Probably there are other similar cases, and there is a 
related problem shown in D156693  (the fix in 
that patch is not correct, the solution here is not good for that case, it is 
possible that the same code as here needs to be changed again or a better fix 
is found). I am accepting this code but probably will create a new patch to 
improve and add tests for similar cases (if not done before by somebody else).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155661/new/

https://reviews.llvm.org/D155661

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155661: [clang][ASTImporter] Fix friend class template import within dependent context

2023-07-31 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:2862-2866
+  bool ShouldAddRedecl = !(IsFriendTemplate && IsDependentContext);
+
   // We may already have a record of the same name; try to find and match it.
   RecordDecl *PrevDecl = nullptr;
   if (!DC->isFunctionOrMethod() && !D->isLambda()) {

The code seems to work but I was confused by the different conditions used (is 
it possible that `IsFriendTemplate` and `ShouldAddRedecl` is true at the same 
time?). I had the observation that if `ShouldAddRedecl` is false we do not need 
the whole search for previous decl. At a friend template we shall not find a 
definition, the loop would just find the last declaration (this value is not 
used). So I have the idea of this code (could not find the "suggest edit" 
command):

```
  bool DependentFriend = IsFriendTemplate && IsDependentContext;

  // We may already have a record of the same name; try to find and match it.
  RecordDecl *PrevDecl = nullptr;
  if (!DependentFriend && !DC->isFunctionOrMethod() && !D->isLambda()) {

```



Comment at: clang/lib/AST/ASTImporter.cpp:2904
 
-if (IsStructuralMatch(D, FoundRecord)) {
+if (IsFriendTemplate || IsStructuralMatch(D, FoundRecord)) {
   RecordDecl *FoundDef = FoundRecord->getDefinition();

This change is not needed if the code above is used.



Comment at: clang/lib/AST/ASTImporter.cpp:2976
+  D2CXX, D, Importer.getToContext(), D->getTagKind(), DC,
+  *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
+  ShouldAddRedecl ? cast_or_null(PrevDecl)

This change is not needed if the code above is used.



Comment at: clang/lib/AST/ASTImporter.cpp:5805-5812
+  bool IsDependentContext = DC != LexicalDC ? LexicalDC->isDependentContext()
+: DC->isDependentContext();
+  bool ShouldAddRedecl = !(IsFriendTemplate && IsDependentContext);
+
   ClassTemplateDecl *FoundByLookup = nullptr;
 
   // We may already have a template of the same name; try to find and match it.

Similar change here:
```
  bool DependentFriend = IsFriendTemplate && IsDependentContext;

  ClassTemplateDecl *FoundByLookup = nullptr;

  // We may already have a template of the same name; try to find and match it.
  if (!DependentFriend && !DC->isFunctionOrMethod()) {
```
`IsFriendTemplate` and `ShouldAddRedecl` is not needed (no changes in the later 
lines).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155661/new/

https://reviews.llvm.org/D155661

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156201: [ASTImporter] Fix corrupted RecordLayout introduced by circular referenced fields

2023-07-28 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:7418
+
+  return UO;
 }

Why is it better to use `CreateEmpty` instead of the old code? Does `Create` do 
something that does not work at this situation (probably getting the layout)? 
If yes the same should be done later at some point, can you explain how this 
works?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156201/new/

https://reviews.llvm.org/D156201

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155574: [clang][ASTImporter] Fix import of recursive field initializer.

2023-07-27 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf4438385d4d9: [clang][ASTImporter] Fix import of recursive 
field initializer. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155574/new/

https://reviews.llvm.org/D155574

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/unittests/AST/ASTImporterTest.cpp

Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -8165,6 +8165,83 @@
   EXPECT_TRUE(ToX->getInClassInitializer());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) {
+  const char *Code =
+  R"(
+  struct AP_TECS;
+
+  struct AP_Landing {
+AP_TECS *TECS_controller;
+  };
+
+  struct AP_TECS {
+AP_Landing landing;
+  };
+
+  class Plane {
+AP_TECS TECS_controller{landing};
+AP_Landing landing{_controller};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+
+  auto *FromR = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("Plane")));
+  for (FieldDecl *F : FromR->fields())
+EXPECT_TRUE(F->getInClassInitializer());
+  auto *ToR = Import(FromR, Lang_CXX11);
+  for (FieldDecl *F : ToR->fields())
+EXPECT_TRUE(F->getInClassInitializer());
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportFieldInitializerWithItself) {
+  const char *Code =
+  R"(
+  class A {
+int a{a};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("A")));
+  EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer1) {
+  // FIXME: This is a example of recursive field initialization that is not
+  // supported.
+  // The following import chain occurs (not complete):
+  // import of A => A.a => in-class initializer of A.a => ref_B() => B => B.b
+  // => in-class initializer of B.b => ref_A() => CXXConstructExpr for A =>
+  // CXXDefaultInitExpr for A.a => in-class initializer of A.a
+  // in-class initializer of A.a is created in two different instances in this
+  // case (import of FieldDecl and CXXDefaultInitExpr). Probably not a big
+  // problem because it is an Expr (the second construction can be ignored
+  // instead of assert). But such recursive init code should not occur in
+  // practice.
+  const char *Code =
+  R"(
+  static int ref_A();
+  static int ref_B();
+  struct A {
+int a = ref_B();
+  };
+  struct B {
+int b = ref_A();
+  };
+  int ref_B() { B b; return b.b; }
+  int ref_A() { A a; return a.a; }
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("A")));
+  EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
+  // auto *ToA = Import(FromA, Lang_CXX11);
+  // EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
   Decl *FromTU = getTuDecl(
   R"(
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3925,7 +3925,6 @@
   auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
   auto ToBitWidth = importChecked(Err, D->getBitWidth());
   auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
-  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
   if (Err)
 return std::move(Err);
   const Type *ToCapturedVLAType = nullptr;
@@ -3948,12 +3947,24 @@
 return std::move(Err);
   ToField->setAccess(D->getAccess());
   ToField->setLexicalDeclContext(LexicalDC);
-  if (ToInitializer)
-ToField->setInClassInitializer(ToInitializer);
   ToField->setImplicit(D->isImplicit());
   if (ToCapturedVLAType)
 ToField->setCapturedVLAType(cast(ToCapturedVLAType));
   LexicalDC->addDeclInternal(ToField);
+  // Import initializer only after the field was created, it may have recursive
+  // reference to the field.
+  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
+  if (Err)
+return std::move(Err);
+  if (ToInitializer) {
+auto *AlreadyImported = ToField->getInClassInitializer();
+if (AlreadyImported)
+  assert(ToInitializer == AlreadyImported &&
+ "Duplicate import of in-class initializer.");
+else
+  ToField->setInClassInitializer(ToInitializer);
+  }
+
   return ToField;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D155574: [clang][ASTImporter] Fix import of recursive field initializer.

2023-07-26 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 544371.
balazske added a comment.

Added check for duplicate import of initializer.
Added more tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155574/new/

https://reviews.llvm.org/D155574

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/unittests/AST/ASTImporterTest.cpp

Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -8107,6 +8107,83 @@
   EXPECT_TRUE(ToX->getInClassInitializer());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) {
+  const char *Code =
+  R"(
+  struct AP_TECS;
+
+  struct AP_Landing {
+AP_TECS *TECS_controller;
+  };
+
+  struct AP_TECS {
+AP_Landing landing;
+  };
+
+  class Plane {
+AP_TECS TECS_controller{landing};
+AP_Landing landing{_controller};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+
+  auto *FromR = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("Plane")));
+  for (FieldDecl *F : FromR->fields())
+EXPECT_TRUE(F->getInClassInitializer());
+  auto *ToR = Import(FromR, Lang_CXX11);
+  for (FieldDecl *F : ToR->fields())
+EXPECT_TRUE(F->getInClassInitializer());
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportFieldInitializerWithItself) {
+  const char *Code =
+  R"(
+  class A {
+int a{a};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("A")));
+  EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer1) {
+  // FIXME: This is a example of recursive field initialization that is not
+  // supported.
+  // The following import chain occurs (not complete):
+  // import of A => A.a => in-class initializer of A.a => ref_B() => B => B.b
+  // => in-class initializer of B.b => ref_A() => CXXConstructExpr for A =>
+  // CXXDefaultInitExpr for A.a => in-class initializer of A.a
+  // in-class initializer of A.a is created in two different instances in this
+  // case (import of FieldDecl and CXXDefaultInitExpr). Probably not a big
+  // problem because it is an Expr (the second construction can be ignored
+  // instead of assert). But such recursive init code should not occur in
+  // practice.
+  const char *Code =
+  R"(
+  static int ref_A();
+  static int ref_B();
+  struct A {
+int a = ref_B();
+  };
+  struct B {
+int b = ref_A();
+  };
+  int ref_B() { B b; return b.b; }
+  int ref_A() { A a; return a.a; }
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("A")));
+  EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
+  // auto *ToA = Import(FromA, Lang_CXX11);
+  // EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
   Decl *FromTU = getTuDecl(
   R"(
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3902,7 +3902,6 @@
   auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
   auto ToBitWidth = importChecked(Err, D->getBitWidth());
   auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
-  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
   if (Err)
 return std::move(Err);
   const Type *ToCapturedVLAType = nullptr;
@@ -3925,12 +3924,24 @@
 return std::move(Err);
   ToField->setAccess(D->getAccess());
   ToField->setLexicalDeclContext(LexicalDC);
-  if (ToInitializer)
-ToField->setInClassInitializer(ToInitializer);
   ToField->setImplicit(D->isImplicit());
   if (ToCapturedVLAType)
 ToField->setCapturedVLAType(cast(ToCapturedVLAType));
   LexicalDC->addDeclInternal(ToField);
+  // Import initializer only after the field was created, it may have recursive
+  // reference to the field.
+  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
+  if (Err)
+return std::move(Err);
+  if (ToInitializer) {
+auto *AlreadyImported = ToField->getInClassInitializer();
+if (AlreadyImported)
+  assert(ToInitializer == AlreadyImported &&
+ "Duplicate import of in-class initializer.");
+else
+  ToField->setInClassInitializer(ToInitializer);
+  }
+
   return ToField;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155574: [clang][ASTImporter] Fix import of recursive field initializer.

2023-07-26 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:3936-3937
+return std::move(Err);
+  if (ToInitializer)
+ToField->setInClassInitializer(ToInitializer);
   return ToField;

danix800 wrote:
> Initializer could indirectly depends on this field and set the initializer 
> while importing.
> `setInClassInitializer()` asserts that initializer should not be set more 
> than once:
> 
> ```
> static int ref_A();
> static int ref_B();
> struct A {
>   int a = ref_B();
> };
> struct B {
>   int b = ref_A();
> };
> int ref_B() { B b; return b.b; }
> int ref_A() { A a; return a.a; }
> ```
This example code really causes problems. But import of `Expr` is not checked 
for recursion, the assertion in the new code fails for this test.

Why do you want to use such code? It looks to cause infinite loop when 
executed. Even code like `class A { int b{b}; };` is probably not correct.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155574/new/

https://reviews.llvm.org/D155574

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155574: [clang][ASTImporter] Fix import of recursive field initializer.

2023-07-20 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 542383.
balazske added a comment.

using clang-format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155574/new/

https://reviews.llvm.org/D155574

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/unittests/AST/ASTImporterTest.cpp


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -8107,6 +8107,23 @@
   EXPECT_TRUE(ToX->getInClassInitializer());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) {
+  const char *Code =
+  R"(
+  class A {
+int b{b};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+
+  auto *FromB =
+  FirstDeclMatcher().match(FromTU, fieldDecl(hasName("b")));
+  EXPECT_TRUE(FromB->hasInClassInitializer());
+
+  auto *ToB = Import(FromB, Lang_CXX11);
+  EXPECT_TRUE(ToB->hasInClassInitializer());
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
   Decl *FromTU = getTuDecl(
   R"(
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3902,7 +3902,6 @@
   auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
   auto ToBitWidth = importChecked(Err, D->getBitWidth());
   auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
-  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
   if (Err)
 return std::move(Err);
   const Type *ToCapturedVLAType = nullptr;
@@ -3925,12 +3924,17 @@
 return std::move(Err);
   ToField->setAccess(D->getAccess());
   ToField->setLexicalDeclContext(LexicalDC);
-  if (ToInitializer)
-ToField->setInClassInitializer(ToInitializer);
   ToField->setImplicit(D->isImplicit());
   if (ToCapturedVLAType)
 ToField->setCapturedVLAType(cast(ToCapturedVLAType));
   LexicalDC->addDeclInternal(ToField);
+  // Import initializer only after the field was created, it may have recursive
+  // reference to the field.
+  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
+  if (Err)
+return std::move(Err);
+  if (ToInitializer)
+ToField->setInClassInitializer(ToInitializer);
   return ToField;
 }
 


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -8107,6 +8107,23 @@
   EXPECT_TRUE(ToX->getInClassInitializer());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) {
+  const char *Code =
+  R"(
+  class A {
+int b{b};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+
+  auto *FromB =
+  FirstDeclMatcher().match(FromTU, fieldDecl(hasName("b")));
+  EXPECT_TRUE(FromB->hasInClassInitializer());
+
+  auto *ToB = Import(FromB, Lang_CXX11);
+  EXPECT_TRUE(ToB->hasInClassInitializer());
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
   Decl *FromTU = getTuDecl(
   R"(
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3902,7 +3902,6 @@
   auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
   auto ToBitWidth = importChecked(Err, D->getBitWidth());
   auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
-  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
   if (Err)
 return std::move(Err);
   const Type *ToCapturedVLAType = nullptr;
@@ -3925,12 +3924,17 @@
 return std::move(Err);
   ToField->setAccess(D->getAccess());
   ToField->setLexicalDeclContext(LexicalDC);
-  if (ToInitializer)
-ToField->setInClassInitializer(ToInitializer);
   ToField->setImplicit(D->isImplicit());
   if (ToCapturedVLAType)
 ToField->setCapturedVLAType(cast(ToCapturedVLAType));
   LexicalDC->addDeclInternal(ToField);
+  // Import initializer only after the field was created, it may have recursive
+  // reference to the field.
+  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
+  if (Err)
+return std::move(Err);
+  if (ToInitializer)
+ToField->setInClassInitializer(ToInitializer);
   return ToField;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155715: [clang][analyzer] Improve StdCLibraryFunctions socket send/recv functions.

2023-07-19 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The modeling of send, recv, sendmsg, recvmsg, sendto, recvfrom is changed:
These functions do return 0, except is the message length is 0.
(In sendmsg, recvmsg the length is not checkable but it is more likely
that a message with 0 length is invalid for these functions.)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155715

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c

Index: clang/test/Analysis/std-c-library-functions-POSIX.c
===
--- clang/test/Analysis/std-c-library-functions-POSIX.c
+++ clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -141,6 +141,8 @@
 
 #include "Inputs/std-c-library-functions-POSIX.h"
 
+void clang_analyzer_eval(int);
+
 void test_open(void) {
   open(0, 0); // \
   // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
@@ -150,3 +152,56 @@
   open(0, 0, 0); // \
   // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
 }
+
+void test_recvfrom(int socket, void *restrict buffer, size_t length, int flags,
+   struct sockaddr *restrict address,
+   socklen_t *restrict address_len) {
+  ssize_t Ret = recvfrom(socket, buffer, length, flags, address, address_len);
+  if (Ret == 0)
+clang_analyzer_eval(length == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(length > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_sendto(int socket, const void *message, size_t length, int flags,
+ const struct sockaddr *dest_addr, socklen_t dest_len) {
+  ssize_t Ret = sendto(socket, message, length, flags, dest_addr, dest_len);
+  if (Ret == 0)
+clang_analyzer_eval(length == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(length > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_recv(int sockfd, void *buf, size_t len, int flags) {
+  ssize_t Ret = recv(sockfd, buf, len, flags);
+  if (Ret == 0)
+clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(len > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_send(int sockfd, void *buf, size_t len, int flags) {
+  ssize_t Ret = send(sockfd, buf, len, flags);
+  if (Ret == 0)
+clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
+  if (Ret > 0)
+clang_analyzer_eval(len > 0); // expected-warning{{TRUE}}
+  if (Ret == -1)
+clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}}
+}
+
+void test_recvmsg(int sockfd, struct msghdr *msg, int flags) {
+  ssize_t Ret = recvmsg(sockfd, msg, flags);
+  clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}}
+}
+
+void test_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
+  ssize_t Ret = sendmsg(sockfd, msg, flags);
+  clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}}
+}
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3096,7 +3096,10 @@
 auto Recvfrom =
 Summary(NoEvalCall)
 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
-   ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
+   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
+  ErrnoMustNotBeChecked, GenericSuccessMsg)
+.Case({ReturnValueCondition(WithinRange, SingleValue(0)),
+   ArgumentCondition(2, WithinRange, SingleValue(0))},
   ErrnoMustNotBeChecked, GenericSuccessMsg)
 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
 .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
@@ -3123,7 +3126,10 @@
 auto Sendto =
 Summary(NoEvalCall)
 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
-   ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
+   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
+  ErrnoMustNotBeChecked, GenericSuccessMsg)
+

[PATCH] D155445: [analyzer][docs] Add CSA release notes

2023-07-19 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/docs/ReleaseNotes.rst:964
+- ``StdCLibraryFunctionArgs`` was merged into the ``StdCLibraryFunctions``.
+  The diagnostics of the ``StdCLibraryFunctions`` was improved.
+  (`4f0436dd1532 `_,

The checker checks for much more functions in POSIX mode.
These additional commits:
6dccf5b8d550911f06e492a3a75c640c05efdab3
f12808ab20369c85ddb602e5a78bab40d16bb83f
39670ae3b93470b2d29fe78e6d40c5d82a05e4a1


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155445/new/

https://reviews.llvm.org/D155445

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154509: [clang][analyzer] StdLibraryFunctionsChecker: Allow NULL buffer in `fread` and `fwrite` if size is zero.

2023-07-19 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
balazske marked an inline comment as done.
Closed by commit rGe271049bc6a1: [clang][analyzer] StdLibraryFunctionsChecker: 
Allow NULL buffer in `fread` and… (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154509/new/

https://reviews.llvm.org/D154509

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c

Index: clang/test/Analysis/std-c-library-functions-arg-constraints.c
===
--- clang/test/Analysis/std-c-library-functions-arg-constraints.c
+++ clang/test/Analysis/std-c-library-functions-arg-constraints.c
@@ -184,6 +184,44 @@
 // bugpath-warning{{The 1st argument to 'fread' is NULL but should not be NULL}} \
 // bugpath-note{{The 1st argument to 'fread' is NULL but should not be NULL}}
 }
+
+int __not_null_buffer(void *, int, int);
+
+void test_notnull_buffer_1(void *buf) {
+  __not_null_buffer(buf, 0, 1);
+  clang_analyzer_eval(buf != 0); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // report-warning{{FALSE}} \
+  // bugpath-warning{{FALSE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{FALSE}} \
+  // bugpath-note{{Assuming 'buf' is equal to null}} \
+  // bugpath-note{{Assuming 'buf' is not equal to null}}
+}
+
+void test_notnull_buffer_2(void *buf) {
+  __not_null_buffer(buf, 1, 0);
+  clang_analyzer_eval(buf != 0); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // report-warning{{FALSE}} \
+  // bugpath-warning{{FALSE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{FALSE}} \
+  // bugpath-note{{Assuming 'buf' is equal to null}} \
+  // bugpath-note{{Assuming 'buf' is not equal to null}}
+}
+
+void test_notnull_buffer_3(void *buf) {
+  __not_null_buffer(buf, 1, 1);
+  clang_analyzer_eval(buf != 0); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{'buf' is not equal to null}}
+}
+
 void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) {
   if (fp) // \
   // bugpath-note{{Assuming 'fp' is null}} \
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -403,6 +403,53 @@
 }
   };
 
+  /// Check null or non-null-ness of an argument that is of pointer type.
+  /// The argument is meant to be a buffer that has a size constraint, and it
+  /// is allowed to have a NULL value if the size is 0. The size can depend on
+  /// 1 or 2 additional arguments, if one of these is 0 the buffer is allowed to
+  /// be NULL. This is useful for functions like `fread` which have this special
+  /// property.
+  class NotNullBufferConstraint : public ValueConstraint {
+using ValueConstraint::ValueConstraint;
+ArgNo SizeArg1N;
+std::optional SizeArg2N;
+// This variable has a role when we negate the constraint.
+bool CannotBeNull = true;
+
+  public:
+NotNullBufferConstraint(ArgNo ArgN, ArgNo SizeArg1N,
+std::optional SizeArg2N,
+bool CannotBeNull = true)
+: ValueConstraint(ArgN), SizeArg1N(SizeArg1N), SizeArg2N(SizeArg2N),
+  CannotBeNull(CannotBeNull) {}
+
+ProgramStateRef apply(ProgramStateRef State, const CallEvent ,
+  const Summary ,
+  CheckerContext ) const override;
+
+void describe(DescriptionKind DK, const CallEvent ,
+  ProgramStateRef State, const Summary ,
+  llvm::raw_ostream ) const override;
+
+bool describeArgumentValue(const CallEvent , ProgramStateRef State,
+   const Summary ,
+   llvm::raw_ostream ) const override;
+
+ValueConstraintPtr negate() const override {
+  NotNullBufferConstraint Tmp(*this);
+  Tmp.CannotBeNull = !this->CannotBeNull;
+  return std::make_shared(Tmp);
+}
+
+  protected:
+bool checkSpecificValidity(const FunctionDecl *FD) const override {
+  const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
+  assert(ValidArg &&
+ "This constraint should be applied only on a pointer type");
+  return ValidArg;
+}
+  };
+
   // Represents a buffer argument with an additional size constraint. The
   // constraint may be a concrete value, or a symbolic value in an argument.
   // Example 1. Concrete value as the minimum buffer size.
@@ -1140,6 +1187,54 @@
   return true;
 }
 
+ProgramStateRef StdLibraryFunctionsChecker::NotNullBufferConstraint::apply(
+ProgramStateRef State, 

[PATCH] D154509: [clang][analyzer] StdLibraryFunctionsChecker: Allow NULL buffer in `fread` and `fwrite` if size is zero.

2023-07-19 Thread Balázs Kéri via Phabricator via cfe-commits
balazske marked an inline comment as done.
balazske added inline comments.



Comment at: 
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:413-414
+using ValueConstraint::ValueConstraint;
+ArgNo SizeArg1N;
+std::optional SizeArg2N;
+// This variable has a role when we negate the constraint.

donat.nagy wrote:
> What would you think about a `SmallVector<2>` for these? It would allow you 
> to handle them with a (short) for loop instead of separate commands.
It does not look to be much better, the only place where a loop can be used is 
in the `apply` function but because optionals (that are to be checked at both 
values) it is not much better. And a vector could be constructed in the `apply` 
function too, but for 2 elements it is not important.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154509/new/

https://reviews.llvm.org/D154509

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155574: [clang][ASTImporter] Fix import of recursive field initializer.

2023-07-18 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, martong, gamesh411, Szelethus, dkrupp.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Import of field initializers with circular reference was not working,
this is fixed now.

Fixes issue #63120


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155574

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/unittests/AST/ASTImporterTest.cpp


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -8107,6 +8107,24 @@
   EXPECT_TRUE(ToX->getInClassInitializer());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ImportRecursiveFieldInitializer) {
+  const char *Code =
+  R"(
+  class A {
+int b{b};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+
+  auto *FromB =
+  FirstDeclMatcher().match(FromTU, fieldDecl(hasName("b")));
+  EXPECT_TRUE(FromB->hasInClassInitializer());
+
+  auto *ToB = Import(FromB, Lang_CXX11);
+  EXPECT_TRUE(ToB->hasInClassInitializer());
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
   Decl *FromTU = getTuDecl(
   R"(
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3902,7 +3902,6 @@
   auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
   auto ToBitWidth = importChecked(Err, D->getBitWidth());
   auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
-  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
   if (Err)
 return std::move(Err);
   const Type *ToCapturedVLAType = nullptr;
@@ -3925,12 +3924,17 @@
 return std::move(Err);
   ToField->setAccess(D->getAccess());
   ToField->setLexicalDeclContext(LexicalDC);
-  if (ToInitializer)
-ToField->setInClassInitializer(ToInitializer);
   ToField->setImplicit(D->isImplicit());
   if (ToCapturedVLAType)
 ToField->setCapturedVLAType(cast(ToCapturedVLAType));
   LexicalDC->addDeclInternal(ToField);
+  // Import initializer only after the field was created, it may have recursive
+  // reference to the field.
+  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
+  if (Err)
+return std::move(Err);
+  if (ToInitializer)
+ToField->setInClassInitializer(ToInitializer);
   return ToField;
 }
 


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -8107,6 +8107,24 @@
   EXPECT_TRUE(ToX->getInClassInitializer());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ImportRecursiveFieldInitializer) {
+  const char *Code =
+  R"(
+  class A {
+int b{b};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+
+  auto *FromB =
+  FirstDeclMatcher().match(FromTU, fieldDecl(hasName("b")));
+  EXPECT_TRUE(FromB->hasInClassInitializer());
+
+  auto *ToB = Import(FromB, Lang_CXX11);
+  EXPECT_TRUE(ToB->hasInClassInitializer());
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
   Decl *FromTU = getTuDecl(
   R"(
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3902,7 +3902,6 @@
   auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
   auto ToBitWidth = importChecked(Err, D->getBitWidth());
   auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
-  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
   if (Err)
 return std::move(Err);
   const Type *ToCapturedVLAType = nullptr;
@@ -3925,12 +3924,17 @@
 return std::move(Err);
   ToField->setAccess(D->getAccess());
   ToField->setLexicalDeclContext(LexicalDC);
-  if (ToInitializer)
-ToField->setInClassInitializer(ToInitializer);
   ToField->setImplicit(D->isImplicit());
   if (ToCapturedVLAType)
 ToField->setCapturedVLAType(cast(ToCapturedVLAType));
   LexicalDC->addDeclInternal(ToField);
+  // Import initializer only after the field was created, it may have recursive
+  // reference to the field.
+  auto ToInitializer = importChecked(Err, D->getInClassInitializer());
+  if (Err)
+return std::move(Err);
+  if (ToInitializer)
+ToField->setInClassInitializer(ToInitializer);
   return ToField;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-07-18 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf12808ab2036: [clang][analyzer] Display notes in 
StdLibraryFunctionsChecker only if… (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -13,7 +13,6 @@
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
-  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -22,7 +21,6 @@
   }
   rewind(F2);
   fclose(F2);
-  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -59,7 +57,6 @@
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{'fopen' is successful}}
-  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -68,7 +65,6 @@
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{'fopen' is successful}}
-  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -107,16 +103,13 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
-  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
-// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -129,12 +122,10 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
-  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -143,7 +134,6 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
-  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
 // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -155,11 +145,9 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
-  // stdargs-note@-1 {{'fread' fails}}
   if (ferror(F)) {// expected-note {{Taking false branch}}
   } else {
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -11,7 +11,6 @@
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
   // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
-  // expected-note@-2{{'fopen' is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -24,7 +23,6 @@
 void check_tmpfile(void) {
   FILE *F = tmpfile();
   // expected-note@-1{{'errno' may be undefined 

[PATCH] D154423: [clang][analyzer] Add all success/failure messages to StdLibraryFunctionsChecker.

2023-07-18 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6dccf5b8d550: [clang][analyzer] Add all success/failure 
messages to… (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154423/new/

https://reviews.llvm.org/D154423

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
  clang/test/Analysis/std-c-library-functions-POSIX.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.c

Index: clang/test/Analysis/std-c-library-functions-arg-constraints.c
===
--- clang/test/Analysis/std-c-library-functions-arg-constraints.c
+++ clang/test/Analysis/std-c-library-functions-arg-constraints.c
@@ -316,6 +316,7 @@
   // bugpath-note{{The 1st argument to 'linkat' is -22 but should be a valid file descriptor or AT_FDCWD}}
 
   // no warning for these functions if the AT_FDCWD value is used
+  (void)openat(AT_FDCWD, "path", 0);
   (void)linkat(AT_FDCWD, "from", AT_FDCWD, "to", 0);
   (void)faccessat(AT_FDCWD, "path", 0, 0);
   (void)symlinkat("oldpath", AT_FDCWD, "newpath");
Index: clang/test/Analysis/std-c-library-functions-POSIX.c
===
--- clang/test/Analysis/std-c-library-functions-POSIX.c
+++ clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -1,3 +1,12 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:DisplayLoadedSummaries=true \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -triple i686-unknown-linux -verify
+
 // RUN: %clang_analyze_cc1 %s \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
@@ -15,6 +24,8 @@
 // CHECK: Loaded summary for: int fileno(FILE *stream)
 // CHECK: Loaded summary for: long a64l(const char *str64)
 // CHECK: Loaded summary for: char *l64a(long value)
+// CHECK: Loaded summary for: int open(const char *path, int oflag, ...)
+// CHECK: Loaded summary for: int openat(int fd, const char *path, int oflag, ...)
 // CHECK: Loaded summary for: int access(const char *pathname, int amode)
 // CHECK: Loaded summary for: int faccessat(int dirfd, const char *pathname, int mode, int flags)
 // CHECK: Loaded summary for: int dup(int fildes)
@@ -82,6 +93,7 @@
 // CHECK: Loaded summary for: int execv(const char *path, char *const argv[])
 // CHECK: Loaded summary for: int execvp(const char *file, char *const argv[])
 // CHECK: Loaded summary for: int getopt(int argc, char *const argv[], const char *optstring)
+// CHECK: Loaded summary for: int socket(int domain, int type, int protocol)
 // CHECK: Loaded summary for: int accept(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len)
 // CHECK: Loaded summary for: int bind(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len)
 // CHECK: Loaded summary for: int getpeername(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len)
@@ -97,6 +109,7 @@
 // CHECK: Loaded summary for: int getsockopt(int socket, int level, int option_name, void *restrict option_value, socklen_t *restrict option_len)
 // CHECK: Loaded summary for: ssize_t send(int sockfd, const void *buf, size_t len, int flags)
 // CHECK: Loaded summary for: int socketpair(int domain, int type, int protocol, int sv[2])
+// CHECK: Loaded summary for: int shutdown(int socket, int how)
 // CHECK: Loaded summary for: int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags)
 // CHECK: Loaded summary for: int utime(const char *filename, struct utimbuf *buf)
 // CHECK: Loaded summary for: int futimens(int fd, const struct timespec times[2])
@@ -128,8 +141,12 @@
 
 #include "Inputs/std-c-library-functions-POSIX.h"
 
-// Must have at least one call expression to initialize the summary map.
-int bar(void);
-void foo(void) {
-  bar();
+void test_open(void) {
+  open(0, 0); // \
+  // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
+}
+
+void test_open_additional_arg(void) {
+  open(0, 0, 0); // \
+  // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
 }
Index: clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
===
--- clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
+++ clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
@@ -47,6 +47,8 @@
 int fileno(FILE *stream);
 long a64l(const char *str64);
 char *l64a(long 

[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-07-18 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG39670ae3b934: [clang][analyzer] Add and change NoteTags in 
StdLibraryFunctionsChecker. (authored by balazske).

Changed prior to commit:
  https://reviews.llvm.org/D153612?vs=540015=541353#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -7,11 +7,13 @@
 
 void check_note_at_correct_open(void) {
   FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -20,6 +22,7 @@
   }
   rewind(F2);
   fclose(F2);
+  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -27,6 +30,7 @@
 
 void check_note_fopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -37,11 +41,13 @@
 
 void check_note_freopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  // stdargs-note@-1 {{'freopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -52,6 +58,8 @@
 
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -59,6 +67,8 @@
 // expected-note@-4 {{Taking false branch}}
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -84,6 +94,7 @@
 void check_track_null(void) {
   FILE *F;
   F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}}
+  // stdargs-note@-1 {{'fopen' fails}}
   if (F != NULL) {  // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}}
 fclose(F);
 return;
@@ -96,13 +107,16 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -115,10 +129,12 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -127,6 +143,7 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file 

[PATCH] D154764: [ASTImporter] Fields are imported first and reordered for correct layout.

2023-07-17 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

If I see correctly this change does that the re-ordered members are imported 
before all other, specially fields come before functions. This way order of 
fields is already correct when a function is imported.




Comment at: clang/lib/AST/ASTImporter.cpp:1863
+  continue;
+}
 ExpectedDecl ImportedOrErr = import(From);

Braces are not required here (and at the other similar places).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154764/new/

https://reviews.llvm.org/D154764

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-07-17 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

No major problems were indicated with the patch stack, I plan to merge all of 
these soon. Small problems can be still corrected before or when the checker is 
put out from the alpha package.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154423: [clang][analyzer] Add all success/failure messages to StdLibraryFunctionsChecker.

2023-07-14 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

About the "`fileno` with standard stream" problem: I do not see an always good 
solution for this case because these standard streams are global variables. If 
we want to be exact, we can not know much about these at analysis start unless 
it is the `main` function. The standard stream variables can be overwritten by 
the program or opened or closed, even if not, any unknown function can change 
the state of these. Because the possibility to change these, the file number 
can change.
At least it is possible to add a checker option for "the program does not 
manipulate standard streams". If this is true the standard streams are 
different values from all other opened streams and the file number is known. 
This can be the default value, most programs probably work this way.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154423/new/

https://reviews.llvm.org/D154423

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-07-13 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 540015.
balazske marked 6 inline comments as done.
balazske added a comment.

Changed format string back to `str().c_str()`,
changed `dyn_cast_or_null`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -7,11 +7,13 @@
 
 void check_note_at_correct_open(void) {
   FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -20,6 +22,7 @@
   }
   rewind(F2);
   fclose(F2);
+  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -27,6 +30,7 @@
 
 void check_note_fopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -37,11 +41,13 @@
 
 void check_note_freopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  // stdargs-note@-1 {{'freopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -52,6 +58,8 @@
 
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -59,6 +67,8 @@
 // expected-note@-4 {{Taking false branch}}
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -84,6 +94,7 @@
 void check_track_null(void) {
   FILE *F;
   F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}}
+  // stdargs-note@-1 {{'fopen' fails}}
   if (F != NULL) {  // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}}
 fclose(F);
 return;
@@ -96,13 +107,16 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -115,10 +129,12 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -127,6 +143,7 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking 

[PATCH] D154983: [clang-extdef-mapping] register necessary targest for ms-style asm block

2023-07-12 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

I do not have the knowledge to approve this change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154983/new/

https://reviews.llvm.org/D154983

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-07-12 Thread Balázs Kéri via Phabricator via cfe-commits
balazske marked 3 inline comments as done.
balazske added inline comments.



Comment at: clang/test/Analysis/stream-note.c:61-62
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)

steakhal wrote:
> Why are these notes doubled?
There are 2 cases of resource leak reported (for `F1` and `F2`) and a note tag 
is there for both of these.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154701: [clang] Overridden CXXMethodDecl::isVirtual() assertion failed before fully imported.

2023-07-11 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

It is possible to reproduce the same problem with this test added to 
ASTImporterTest.cpp:

  TEST_P(ASTImporterOptionSpecificTestBase, ImportVirtualOverriddenMethodTest) {
const char *Code =
R"(
void f1();
class A {
  virtual void f(){}
};
class B: public A {
  void f() override {
f1();
  }
};
class C: public B {
  void f() override {}
};
void f1() { C c; }
)";
Decl *FromTU = getTuDecl(Code, Lang_CXX11);
  
auto *FromF = FirstDeclMatcher().match(
FromTU, cxxMethodDecl(hasName("B::f")));
  
auto *ToBF = Import(FromF, Lang_CXX11);
EXPECT_TRUE(ToBF->isVirtual());
  
auto *ToCF = FirstDeclMatcher().match(
ToBF->getTranslationUnitDecl(), cxxMethodDecl(hasName("C::f")));
EXPECT_TRUE(ToCF->isVirtual());
  }

I am not opposed to removal of the assertion as fix because it looks not very 
important (probably it can be replaced by another assertion for example to not 
allow constructors here, see this 

 commit) but another person in the AST area should check this.




Comment at: clang/test/Analysis/ctu-astimport-virtual-assertion/main.cpp:22
+
+#include "Inputs/input.h"

Such tests are not in the //Analysis// folder but in the //ASTMerge// folder 
instead. I would say that this test is not necessary if the other test (in my 
added note) is inserted.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154701/new/

https://reviews.llvm.org/D154701

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154709: [clang][ASTImporter] Add a 'Message' member to ASTImportError and use it throughout ASTImporter

2023-07-10 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

The goal is to have a message always in `ASTImportError`? Then probably the 
constructor without message can be removed, at least to check if really the 
message is added at all places. I found that it is missing in 
`VisitObjCImplementationDecl`.
I do not know what happens with messages passed to `FromDiag` or `ToDiag` and 
if these are available somehow to LLDB. Otherwise it would be even better to 
remove all FromDiag and ToDiag messages from `ASTImporter` and put these 
messages into `ASTImportError` and use later in the way that is needed by the 
use case. This would require to pass a message to `HandleNameConflict` but then 
we have always the detailed message. There are places where diagnostic is 
generated but there is no error, we should check if this is correct and if we 
can remove the diagnostic or make import error.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154709/new/

https://reviews.llvm.org/D154709

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154423: [clang][analyzer] Add all success/failure messages to StdLibraryFunctionsChecker.

2023-07-10 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

It would be more simple to handle the standard streams in `StreamChecker` only. 
There it is possible to detect standard streams (should be variables with the 
known names) as arguments to functions. If `StreamChecker` eliminates the 
failure branch of `fileno` it will disappear from the analysis (order of 
checker callbacks does not matter, at the end only the correct branch remains). 
If stream checker is not enabled we will still get the failure for 
`fileno(stdin)`. `StdLibraryFunctionsChecker` does not have a mechanism to 
detect special variables to arguments, probably it is possible to implement 
with a special type of argument constraint.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154423/new/

https://reviews.llvm.org/D154423

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154423: [clang][analyzer] Add all success/failure messages to StdLibraryFunctionsChecker.

2023-07-07 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

The standard streams may need special handling, this can be useful for 
`StreamChecker` too. One problem is that the standard streams can be changed by 
the program, so we can not know for sure if these are the original values. 
Still it can be better to assume that `fileno` can not fail if used with the 
standard streams.
The result with `ftell` looks interesting, I checked this case already and I 
think the note tag is missing because there is a hidden conversion so the 
original symbol (that is set to interesting) is different than the real `ftell` 
function call.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154423/new/

https://reviews.llvm.org/D154423

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154509: [clang][analyzer] StdLibraryFunctionsChecker: Allow NULL buffer in `fread` and `fwrite` if size is zero.

2023-07-05 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154509

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c

Index: clang/test/Analysis/std-c-library-functions-arg-constraints.c
===
--- clang/test/Analysis/std-c-library-functions-arg-constraints.c
+++ clang/test/Analysis/std-c-library-functions-arg-constraints.c
@@ -184,6 +184,44 @@
 // bugpath-warning{{The 1st argument to 'fread' is NULL but should not be NULL}} \
 // bugpath-note{{The 1st argument to 'fread' is NULL but should not be NULL}}
 }
+
+int __not_null_buffer(void *, int, int);
+
+void test_notnull_buffer_1(void *buf) {
+  __not_null_buffer(buf, 0, 1);
+  clang_analyzer_eval(buf != 0); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // report-warning{{FALSE}} \
+  // bugpath-warning{{FALSE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{FALSE}} \
+  // bugpath-note{{Assuming 'buf' is equal to null}} \
+  // bugpath-note{{Assuming 'buf' is not equal to null}}
+}
+
+void test_notnull_buffer_2(void *buf) {
+  __not_null_buffer(buf, 1, 0);
+  clang_analyzer_eval(buf != 0); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // report-warning{{FALSE}} \
+  // bugpath-warning{{FALSE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{FALSE}} \
+  // bugpath-note{{Assuming 'buf' is equal to null}} \
+  // bugpath-note{{Assuming 'buf' is not equal to null}}
+}
+
+void test_notnull_buffer_3(void *buf) {
+  __not_null_buffer(buf, 1, 1);
+  clang_analyzer_eval(buf != 0); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{'buf' is not equal to null}}
+}
+
 void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) {
   if (fp) // \
   // bugpath-note{{Assuming 'fp' is null}} \
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -402,6 +402,53 @@
 }
   };
 
+  /// Check null or non-null-ness of an argument that is of pointer type.
+  /// The argument is meant to be a buffer that has a size constraint, and it
+  /// is allowed to have a NULL value if the size is 0. The size can depend on
+  /// 1 or 2 additional arguments, if one of these is 0 the buffer is allowed to
+  /// be NULL. This is useful for functions like `fread` which have this special
+  /// property.
+  class NotNullBufferConstraint : public ValueConstraint {
+using ValueConstraint::ValueConstraint;
+ArgNo SizeArg1N;
+std::optional SizeArg2N;
+// This variable has a role when we negate the constraint.
+bool CannotBeNull = true;
+
+  public:
+NotNullBufferConstraint(ArgNo ArgN, ArgNo SizeArg1N,
+std::optional SizeArg2N,
+bool CannotBeNull = true)
+: ValueConstraint(ArgN), SizeArg1N(SizeArg1N), SizeArg2N(SizeArg2N),
+  CannotBeNull(CannotBeNull) {}
+
+ProgramStateRef apply(ProgramStateRef State, const CallEvent ,
+  const Summary ,
+  CheckerContext ) const override;
+
+void describe(DescriptionKind DK, const CallEvent ,
+  ProgramStateRef State, const Summary ,
+  llvm::raw_ostream ) const override;
+
+bool describeArgumentValue(const CallEvent , ProgramStateRef State,
+   const Summary ,
+   llvm::raw_ostream ) const override;
+
+ValueConstraintPtr negate() const override {
+  NotNullBufferConstraint Tmp(*this);
+  Tmp.CannotBeNull = !this->CannotBeNull;
+  return std::make_shared(Tmp);
+}
+
+  protected:
+bool checkSpecificValidity(const FunctionDecl *FD) const override {
+  const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
+  assert(ValidArg &&
+ "This constraint should be applied only on a pointer type");
+  return ValidArg;
+}
+  };
+
   // Represents a buffer argument with an additional size constraint. The
   // constraint may be a concrete value, or a symbolic value in an argument.
   // Example 1. Concrete value as the minimum buffer size.
@@ -1141,6 +1188,54 @@
   return true;
 }
 
+ProgramStateRef 

[PATCH] D154423: [clang][analyzer] Add all success/failure messages to StdLibraryFunctionsChecker.

2023-07-05 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 537346.
balazske added a comment.

Added AT_FDCWD `openat` test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154423/new/

https://reviews.llvm.org/D154423

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
  clang/test/Analysis/std-c-library-functions-POSIX.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.c

Index: clang/test/Analysis/std-c-library-functions-arg-constraints.c
===
--- clang/test/Analysis/std-c-library-functions-arg-constraints.c
+++ clang/test/Analysis/std-c-library-functions-arg-constraints.c
@@ -316,6 +316,7 @@
   // bugpath-note{{The 1st argument to 'linkat' is -22 but should be a valid file descriptor or AT_FDCWD}}
 
   // no warning for these functions if the AT_FDCWD value is used
+  (void)openat(AT_FDCWD, "path", 0);
   (void)linkat(AT_FDCWD, "from", AT_FDCWD, "to", 0);
   (void)faccessat(AT_FDCWD, "path", 0, 0);
   (void)symlinkat("oldpath", AT_FDCWD, "newpath");
Index: clang/test/Analysis/std-c-library-functions-POSIX.c
===
--- clang/test/Analysis/std-c-library-functions-POSIX.c
+++ clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -1,3 +1,12 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:DisplayLoadedSummaries=true \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -triple i686-unknown-linux -verify
+
 // RUN: %clang_analyze_cc1 %s \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
@@ -15,6 +24,8 @@
 // CHECK: Loaded summary for: int fileno(FILE *stream)
 // CHECK: Loaded summary for: long a64l(const char *str64)
 // CHECK: Loaded summary for: char *l64a(long value)
+// CHECK: Loaded summary for: int open(const char *path, int oflag, ...)
+// CHECK: Loaded summary for: int openat(int fd, const char *path, int oflag, ...)
 // CHECK: Loaded summary for: int access(const char *pathname, int amode)
 // CHECK: Loaded summary for: int faccessat(int dirfd, const char *pathname, int mode, int flags)
 // CHECK: Loaded summary for: int dup(int fildes)
@@ -82,6 +93,7 @@
 // CHECK: Loaded summary for: int execv(const char *path, char *const argv[])
 // CHECK: Loaded summary for: int execvp(const char *file, char *const argv[])
 // CHECK: Loaded summary for: int getopt(int argc, char *const argv[], const char *optstring)
+// CHECK: Loaded summary for: int socket(int domain, int type, int protocol)
 // CHECK: Loaded summary for: int accept(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len)
 // CHECK: Loaded summary for: int bind(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len)
 // CHECK: Loaded summary for: int getpeername(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len)
@@ -97,6 +109,7 @@
 // CHECK: Loaded summary for: int getsockopt(int socket, int level, int option_name, void *restrict option_value, socklen_t *restrict option_len)
 // CHECK: Loaded summary for: ssize_t send(int sockfd, const void *buf, size_t len, int flags)
 // CHECK: Loaded summary for: int socketpair(int domain, int type, int protocol, int sv[2])
+// CHECK: Loaded summary for: int shutdown(int socket, int how)
 // CHECK: Loaded summary for: int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags)
 // CHECK: Loaded summary for: int utime(const char *filename, struct utimbuf *buf)
 // CHECK: Loaded summary for: int futimens(int fd, const struct timespec times[2])
@@ -128,8 +141,12 @@
 
 #include "Inputs/std-c-library-functions-POSIX.h"
 
-// Must have at least one call expression to initialize the summary map.
-int bar(void);
-void foo(void) {
-  bar();
+void test_open(void) {
+  open(0, 0); // \
+  // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
+}
+
+void test_open_additional_arg(void) {
+  open(0, 0, 0); // \
+  // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
 }
Index: clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
===
--- clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
+++ clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
@@ -47,6 +47,8 @@
 int fileno(FILE *stream);
 long a64l(const char *str64);
 char *l64a(long value);
+int open(const char *path, int oflag, ...);
+int openat(int fd, const char *path, int oflag, ...);
 int access(const char 

[PATCH] D154423: [clang][analyzer] Add all success/failure messages to StdLibraryFunctionsChecker.

2023-07-05 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

Results from the last run (the same applies as before, the run postfix `_3` 
must be selected at top right corner):

| memcached_1.6.8_stdclf_notetag_interesting_test_3  | Reports 

  |
| tmux_2.6_stdclf_notetag_interesting_test_3 | Reports 

 |
| curl_curl-7_66_0_stdclf_notetag_interesting_test_3 | Reports 

 |
| twin_v0.8.1_stdclf_notetag_interesting_test_3  | Reports 

  |
| vim_v8.2.1920_stdclf_notetag_interesting_test_3| Reports 

|
| openssl_openssl-3.0.0-alpha7_stdclf_notetag_interesting_test_3 | Reports 

 |
| sqlite_version-3.33.0_stdclf_notetag_interesting_test_3| Reports 

|
| ffmpeg_n4.3.1_stdclf_notetag_interesting_test_3| Reports 

|
| postgres_REL_13_0_stdclf_notetag_interesting_test_3| Reports 

|
| xerces_v3.2.3_stdclf_notetag_interesting_test_3| Reports 

|
| bitcoin_v0.20.1_stdclf_notetag_interesting_test_3  | Reports 

  |


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154423/new/

https://reviews.llvm.org/D154423

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154423: [clang][analyzer] Add all success/failure messages to StdLibraryFunctionsChecker.

2023-07-04 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Success or failure messages are now shown at all checked functions, if the call
(return value) is interesting.
Additionally new functions are added: open, openat, socket, shutdown


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154423

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
  clang/test/Analysis/std-c-library-functions-POSIX.c

Index: clang/test/Analysis/std-c-library-functions-POSIX.c
===
--- clang/test/Analysis/std-c-library-functions-POSIX.c
+++ clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -1,3 +1,12 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:DisplayLoadedSummaries=true \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -triple i686-unknown-linux -verify
+
 // RUN: %clang_analyze_cc1 %s \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
@@ -15,6 +24,8 @@
 // CHECK: Loaded summary for: int fileno(FILE *stream)
 // CHECK: Loaded summary for: long a64l(const char *str64)
 // CHECK: Loaded summary for: char *l64a(long value)
+// CHECK: Loaded summary for: int open(const char *path, int oflag, ...)
+// CHECK: Loaded summary for: int openat(int fd, const char *path, int oflag, ...)
 // CHECK: Loaded summary for: int access(const char *pathname, int amode)
 // CHECK: Loaded summary for: int faccessat(int dirfd, const char *pathname, int mode, int flags)
 // CHECK: Loaded summary for: int dup(int fildes)
@@ -82,6 +93,7 @@
 // CHECK: Loaded summary for: int execv(const char *path, char *const argv[])
 // CHECK: Loaded summary for: int execvp(const char *file, char *const argv[])
 // CHECK: Loaded summary for: int getopt(int argc, char *const argv[], const char *optstring)
+// CHECK: Loaded summary for: int socket(int domain, int type, int protocol)
 // CHECK: Loaded summary for: int accept(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len)
 // CHECK: Loaded summary for: int bind(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len)
 // CHECK: Loaded summary for: int getpeername(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len)
@@ -97,6 +109,7 @@
 // CHECK: Loaded summary for: int getsockopt(int socket, int level, int option_name, void *restrict option_value, socklen_t *restrict option_len)
 // CHECK: Loaded summary for: ssize_t send(int sockfd, const void *buf, size_t len, int flags)
 // CHECK: Loaded summary for: int socketpair(int domain, int type, int protocol, int sv[2])
+// CHECK: Loaded summary for: int shutdown(int socket, int how)
 // CHECK: Loaded summary for: int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags)
 // CHECK: Loaded summary for: int utime(const char *filename, struct utimbuf *buf)
 // CHECK: Loaded summary for: int futimens(int fd, const struct timespec times[2])
@@ -128,8 +141,12 @@
 
 #include "Inputs/std-c-library-functions-POSIX.h"
 
-// Must have at least one call expression to initialize the summary map.
-int bar(void);
-void foo(void) {
-  bar();
+void test_open(void) {
+  open(0, 0); // \
+  // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
+}
+
+void test_open_additional_arg(void) {
+  open(0, 0, 0); // \
+  // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
 }
Index: clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
===
--- clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
+++ clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
@@ -47,6 +47,8 @@
 int fileno(FILE *stream);
 long a64l(const char *str64);
 char *l64a(long value);
+int open(const char *path, int oflag, ...);
+int openat(int fd, const char *path, int oflag, ...);
 int access(const char *pathname, int amode);
 int faccessat(int dirfd, const char *pathname, int mode, int flags);
 int dup(int fildes);
@@ -135,6 +137,7 @@
 } __CONST_SOCKADDR_ARG __attribute__((__transparent_union__));
 #undef __SOCKADDR_ONETYPE
 
+int socket(int domain, int type, int protocol);
 int accept(int 

[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-07-04 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 537003.
balazske added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -13,7 +13,6 @@
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
-  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -22,7 +21,6 @@
   }
   rewind(F2);
   fclose(F2);
-  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -59,7 +57,6 @@
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{'fopen' is successful}}
-  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -68,7 +65,6 @@
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{'fopen' is successful}}
-  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -107,16 +103,13 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
-  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
-// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -129,12 +122,10 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
-  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -143,7 +134,6 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
-  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
 // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -155,11 +145,9 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
-  // stdargs-note@-1 {{'fread' fails}}
   if (ferror(F)) {// expected-note {{Taking false branch}}
   } else {
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -11,7 +11,6 @@
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
   // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
-  // expected-note@-2{{'fopen' is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -24,7 +23,6 @@
 void check_tmpfile(void) {
   FILE *F = tmpfile();
   // expected-note@-1{{'errno' may be undefined after successful call to 'tmpfile'}}
-  // expected-note@-2{{'tmpfile' is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   

[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-07-04 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 537002.
balazske added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -7,11 +7,13 @@
 
 void check_note_at_correct_open(void) {
   FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -20,6 +22,7 @@
   }
   rewind(F2);
   fclose(F2);
+  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -27,6 +30,7 @@
 
 void check_note_fopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -37,11 +41,13 @@
 
 void check_note_freopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  // stdargs-note@-1 {{'freopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -52,6 +58,8 @@
 
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -59,6 +67,8 @@
 // expected-note@-4 {{Taking false branch}}
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -84,6 +94,7 @@
 void check_track_null(void) {
   FILE *F;
   F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}}
+  // stdargs-note@-1 {{'fopen' fails}}
   if (F != NULL) {  // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}}
 fclose(F);
 return;
@@ -96,13 +107,16 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -115,10 +129,12 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -127,6 +143,7 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF 

[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-07-03 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

The success/failure note tags are not added to all functions, `dup` is one of 
these, this means at `dup` no note tag is shown. A next patch can be made to 
add these messages to all functions. The other places look good, but 
CodeChecker is a bit tricky, you must select 
//*_stdclf_notetag_interesting_test_2// at the small arrow after the "found 
in:" text (upper right corner). The link is good but not that instance of the 
bug is displayed because only the note tags are different.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-06-30 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

| results with the latest version:   |
| memcached_1.6.8_stdclf_notetag_interesting_test_2  | Reports 

  |
| tmux_2.6_stdclf_notetag_interesting_test_2 | Reports 

 |
| curl_curl-7_66_0_stdclf_notetag_interesting_test_2 | Reports 

 |
| twin_v0.8.1_stdclf_notetag_interesting_test_2  | Reports 

  |
| vim_v8.2.1920_stdclf_notetag_interesting_test_2| Reports 

|
| openssl_openssl-3.0.0-alpha7_stdclf_notetag_interesting_test_2 | Reports 

 |
| sqlite_version-3.33.0_stdclf_notetag_interesting_test_2| Reports 

|
| ffmpeg_n4.3.1_stdclf_notetag_interesting_test_2| Reports 

|
| postgres_REL_13_0_stdclf_notetag_interesting_test_2| Reports 

|
| xerces_v3.2.3_stdclf_notetag_interesting_test_2| Reports 

|
| bitcoin_v0.20.1_stdclf_notetag_interesting_test_2  | Reports 

  |


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153363: [clang][analyzer] No end-of-file when seek to file begin.

2023-06-30 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2eefd19613b8: [clang][analyzer] No end-of-file when seek to 
file begin. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153363/new/

https://reviews.llvm.org/D153363

Files:
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/stream-error.c

Index: clang/test/Analysis/stream-error.c
===
--- clang/test/Analysis/stream-error.c
+++ clang/test/Analysis/stream-error.c
@@ -146,7 +146,7 @@
   FILE *F = fopen("file", "r");
   if (!F)
 return;
-  int rc = fseek(F, 0, SEEK_SET);
+  int rc = fseek(F, 1, SEEK_SET);
   if (rc) {
 int IsFEof = feof(F), IsFError = ferror(F);
 // Get feof or ferror or no error.
@@ -173,6 +173,35 @@
   fclose(F);
 }
 
+void error_fseek_0(void) {
+  FILE *F = fopen("file", "r");
+  if (!F)
+return;
+  int rc = fseek(F, 0, SEEK_SET);
+  if (rc) {
+int IsFEof = feof(F), IsFError = ferror(F);
+// Get ferror or no error, but not feof.
+clang_analyzer_eval(IsFError);
+// expected-warning@-1 {{FALSE}}
+// expected-warning@-2 {{TRUE}}
+clang_analyzer_eval(IsFEof);
+// expected-warning@-1 {{FALSE}}
+// Error flags should not change.
+clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
+if (IsFError)
+  clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}}
+else
+  clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
+  } else {
+clang_analyzer_eval(feof(F));   // expected-warning {{FALSE}}
+clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
+// Error flags should not change.
+clang_analyzer_eval(feof(F));   // expected-warning {{FALSE}}
+clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
+  }
+  fclose(F);
+}
+
 void error_indeterminate(void) {
   FILE *F = fopen("file", "r+");
   if (!F)
Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -285,7 +285,14 @@
 0}},
   };
 
+  /// Expanded value of EOF, empty before initialization.
   mutable std::optional EofVal;
+  /// Expanded value of SEEK_SET, 0 if not found.
+  mutable int SeekSetVal = 0;
+  /// Expanded value of SEEK_CUR, 1 if not found.
+  mutable int SeekCurVal = 1;
+  /// Expanded value of SEEK_END, 2 if not found.
+  mutable int SeekEndVal = 2;
 
   void evalFopen(const FnDescription *Desc, const CallEvent ,
  CheckerContext ) const;
@@ -432,7 +439,7 @@
 });
   }
 
-  void initEof(CheckerContext ) const {
+  void initMacroValues(CheckerContext ) const {
 if (EofVal)
   return;
 
@@ -441,6 +448,15 @@
   EofVal = *OptInt;
 else
   EofVal = -1;
+if (const std::optional OptInt =
+tryExpandAsInteger("SEEK_SET", C.getPreprocessor()))
+  SeekSetVal = *OptInt;
+if (const std::optional OptInt =
+tryExpandAsInteger("SEEK_END", C.getPreprocessor()))
+  SeekEndVal = *OptInt;
+if (const std::optional OptInt =
+tryExpandAsInteger("SEEK_CUR", C.getPreprocessor()))
+  SeekCurVal = *OptInt;
   }
 
   /// Searches for the ExplodedNode where the file descriptor was acquired for
@@ -488,7 +504,7 @@
 
 void StreamChecker::checkPreCall(const CallEvent ,
  CheckerContext ) const {
-  initEof(C);
+  initMacroValues(C);
 
   const FnDescription *Desc = lookupFn(Call);
   if (!Desc || !Desc->PreFn)
@@ -786,6 +802,11 @@
   if (!State->get(StreamSym))
 return;
 
+  const llvm::APSInt *PosV =
+  C.getSValBuilder().getKnownValue(State, Call.getArgSVal(1));
+  const llvm::APSInt *WhenceV =
+  C.getSValBuilder().getKnownValue(State, Call.getArgSVal(2));
+
   DefinedSVal RetVal = makeRetVal(C, CE);
 
   // Make expression result.
@@ -804,9 +825,12 @@
   // It is possible that fseek fails but sets none of the error flags.
   // If fseek failed, assume that the file position becomes indeterminate in any
   // case.
+  StreamErrorState NewErrS = ErrorNone | ErrorFError;
+  // Setting the position to start of file never produces EOF error.
+  if (!(PosV && *PosV == 0 && WhenceV && *WhenceV == SeekSetVal))
+NewErrS = NewErrS | ErrorFEof;
   StateFailed = StateFailed->set(
-  StreamSym,
-  StreamState::getOpened(Desc, ErrorNone | ErrorFEof | ErrorFError, true));
+  StreamSym, StreamState::getOpened(Desc, NewErrS, true));
 
   C.addTransition(StateNotFailed);
   C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
@@ -1153,7 +1177,7 @@
 return State;
 
   int64_t X = CI->getValue().getSExtValue();
-  if (X >= 0 && X <= 2)
+  if (X == SeekSetVal || X == SeekCurVal || X == SeekEndVal)
 return State;
 
   if (ExplodedNode *N = 

[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-06-30 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 536133.
balazske added a comment.

Rebase to newest parent review version.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -13,7 +13,6 @@
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
-  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -22,7 +21,6 @@
   }
   rewind(F2);
   fclose(F2);
-  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -59,7 +57,6 @@
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{'fopen' is successful}}
-  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -68,7 +65,6 @@
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{'fopen' is successful}}
-  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -107,16 +103,13 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
-  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
-// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -129,12 +122,10 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
-  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -143,7 +134,6 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
-  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
 // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -155,11 +145,9 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
-  // stdargs-note@-1 {{'fread' fails}}
   if (ferror(F)) {// expected-note {{Taking false branch}}
   } else {
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -11,7 +11,6 @@
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
   // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
-  // expected-note@-2{{'fopen' is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -24,7 +23,6 @@
 void check_tmpfile(void) {
   FILE *F = tmpfile();
   // expected-note@-1{{'errno' may be undefined after successful call to 'tmpfile'}}
-  // expected-note@-2{{'tmpfile' is successful}}
   // expected-note@+2{{'F' is non-null}}
   // 

[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-29 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 535800.
balazske added a comment.

Fixed review issues.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -7,11 +7,13 @@
 
 void check_note_at_correct_open(void) {
   FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -20,6 +22,7 @@
   }
   rewind(F2);
   fclose(F2);
+  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -27,6 +30,7 @@
 
 void check_note_fopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -37,11 +41,13 @@
 
 void check_note_freopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  // stdargs-note@-1 {{'freopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -52,6 +58,8 @@
 
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -59,6 +67,8 @@
 // expected-note@-4 {{Taking false branch}}
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -84,6 +94,7 @@
 void check_track_null(void) {
   FILE *F;
   F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}}
+  // stdargs-note@-1 {{'fopen' fails}}
   if (F != NULL) {  // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}}
 fclose(F);
 return;
@@ -96,13 +107,16 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -115,10 +129,12 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -127,6 +143,7 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream 

[PATCH] D153889: [analyzer][NFC] Fix dangling StringRef in barely used code

2023-06-29 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

This is actually needed to get correct bug reports in D153612 
, otherwise I got garbage messages (probably 
a `std::string` stack variable was passed to the `getNoteTag` function). I 
would not say that this is NFC because it is a bugfix.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153889/new/

https://reviews.llvm.org/D153889

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-29 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 535655.
balazske marked 3 inline comments as done.
balazske added a comment.

Fixed review issues.
Note tag is added for `fread`.
Notes contain now the function name.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -7,11 +7,13 @@
 
 void check_note_at_correct_open(void) {
   FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
+  // stdargs-note@-1 {{'tmpfile' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -20,6 +22,7 @@
   }
   rewind(F2);
   fclose(F2);
+  // stdargs-note@-1 {{'fclose' fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -27,6 +30,7 @@
 
 void check_note_fopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -37,11 +41,13 @@
 
 void check_note_freopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  // stdargs-note@-1 {{'freopen' is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -52,6 +58,8 @@
 
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -59,6 +67,8 @@
 // expected-note@-4 {{Taking false branch}}
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{'fopen' is successful}}
+  // stdargs-note@-2 {{'fopen' is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -84,6 +94,7 @@
 void check_track_null(void) {
   FILE *F;
   F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}}
+  // stdargs-note@-1 {{'fopen' fails}}
   if (F != NULL) {  // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}}
 fclose(F);
 return;
@@ -96,13 +107,16 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // expected-note {{Taking true branch}}
 clearerr(F);
 fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+// stdargs-note@-1 {{'fread' fails}}
 if (feof(F)) { // expected-note {{Taking true branch}}
   fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
   // expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
@@ -115,10 +129,12 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{'fopen' is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
   fread(Buf, 1, 1, F);
+  // stdargs-note@-1 {{'fread' is successful}}
   if (feof(F)) { // expected-note {{Taking false branch}}
 fclose(F);
 return;
@@ -127,6 +143,7 @@
 return;
   }
   fread(Buf, 1, 1, F);   // expected-note {{Assuming stream reaches end-of-file here}}
+  // stdargs-note@-1 {{'fread' fails}}
   if (feof(F)) { // 

[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-27 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: 
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:1299
+// StdLibraryFunctionsChecker.
+ExplodedNode *Pred = const_cast(Node);
+if (!Case.getNote().empty()) {

donat.nagy wrote:
> balazske wrote:
> > donat.nagy wrote:
> > > Can you explain why is it safe to use `const_cast` here? (I don't see any 
> > > concrete issue, but the engine has lots of invariants / unwritten rules 
> > > and I fear that this might break one of them.)
> > The node `Pred` should be modified only later when a successor is added 
> > (`addTransition` has non-const parameter).
> I understood that you //need// a non-const `ExplodedNode *` because 
> `addTransition` expects it; I want to understand why you are //allowed to// 
> `const_cast` it (why doesn't this confuse the engine logic).
> 
> Equivalent question from the other direction: Why did the author of 
> `CheckerContext::getPredecessor()` specify that its return value is a 
> //const// pointer to `ExplodedNode`?
> 
> If we can conclude that `const_cast` is valid in this kind of situation, then 
> I'd also consider simply removing the "const" from the return type of 
> `getPredecessor`.
The `const_cast` is not needed at all if `Pred` and `Node` is made non-const, 
and `getPredecessor` has a non-const version. The `Node` is saved because we 
want to add transitions to it, it makes no sense to have it (a pointer to) 
const. (Probably the const comes from a time when the `Node` was used only for 
the lambda? In the lambda it could be const, if it matters.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-27 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 534991.
balazske marked 5 inline comments as done.
balazske added a comment.

Fixed review issues


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -7,11 +7,13 @@
 
 void check_note_at_correct_open(void) {
   FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
+  // stdargs-note@-1 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -20,6 +22,7 @@
   }
   rewind(F2);
   fclose(F2);
+  // stdargs-note@-1 {{call fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -27,6 +30,7 @@
 
 void check_note_fopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -37,11 +41,13 @@
 
 void check_note_freopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -52,6 +58,8 @@
 
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
+  // stdargs-note@-2 {{call is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -59,6 +67,8 @@
 // expected-note@-4 {{Taking false branch}}
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
+  // stdargs-note@-2 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -84,6 +94,7 @@
 void check_track_null(void) {
   FILE *F;
   F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}}
+  // stdargs-note@-1 {{call fails}}
   if (F != NULL) {  // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}}
 fclose(F);
 return;
@@ -96,6 +107,7 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -115,6 +127,7 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -138,6 +151,7 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -10,7 +10,8 @@
 
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
-  // expected-note@-1{{Assuming that function 'fopen' is successful, in this case the value 'errno' may be undefined after the call and should not be used}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
+  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -22,7 +23,8 @@
 
 void check_tmpfile(void) {
   FILE *F = tmpfile();
-  // expected-note@-1{{Assuming that 

[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-06-27 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: 
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:1325
   if (!Pred)
-break;
+continue;
 }

steakhal wrote:
> Why do you continue here? Do you have a case for this?
This is only because the same loop has other failure places (if the state can 
not be applied) where `continue` is used already. The reason is that if one 
`addTransition` fails a next one may succeed. It is probably better to use 
`break` at all places. Even then what was already added to the state can not be 
removed, so it may be not wrong to add all states that can be added.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-06-27 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

Here 

 are results for vim, still the fileno problem is not fixed. This run was made 
before the last update where `markInteresting` is added, then it should work.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-06-27 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 534868.
balazske added a comment.

`markInteresting` must be used at arguments found to be invalid


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153776/new/

https://reviews.llvm.org/D153776

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -13,7 +13,6 @@
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
-  // stdargs-note@-1 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -22,7 +21,6 @@
   }
   rewind(F2);
   fclose(F2);
-  // stdargs-note@-1 {{call fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -59,7 +57,6 @@
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{call is successful}}
-  // stdargs-note@-2 {{call is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -68,7 +65,6 @@
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{call is successful}}
-  // stdargs-note@-2 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -107,7 +103,6 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -127,7 +122,6 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -151,7 +145,6 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -11,7 +11,6 @@
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
   // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
-  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -24,7 +23,6 @@
 void check_tmpfile(void) {
   FILE *F = tmpfile();
   // expected-note@-1{{'errno' may be undefined after successful call to 'tmpfile'}}
-  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -36,14 +34,12 @@
 
 void check_freopen(void) {
   FILE *F = tmpfile();
-  // expected-note@-1{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
 return;
   F = freopen("xxx", "w", F);
   // expected-note@-1{{'errno' may be undefined after successful call to 'freopen'}}
-  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -55,14 +51,12 @@
 
 void check_fclose(void) {
   FILE *F = tmpfile();
-  // expected-note@-1{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
 return;
   (void)fclose(F);
   // expected-note@-1{{'errno' may be undefined after successful call to 'fclose'}}
-  // expected-note@-2{{call is successful}}
   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
   // expected-note@-1{{An undefined value may be read from 'errno'}}
 }
@@ -70,7 +64,6 @@
 void check_fread(void) {
   char Buf[10];
   FILE *F = tmpfile();
-  // expected-note@-1{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -85,7 +78,6 @@
 void check_fwrite(void) {
   char Buf[] = "0123456789";
   FILE *F = tmpfile();
-  // expected-note@-1{{call is successful}}
   // 

[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-27 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: 
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:1299
+// StdLibraryFunctionsChecker.
+ExplodedNode *Pred = const_cast(Node);
+if (!Case.getNote().empty()) {

donat.nagy wrote:
> Can you explain why is it safe to use `const_cast` here? (I don't see any 
> concrete issue, but the engine has lots of invariants / unwritten rules and I 
> fear that this might break one of them.)
The node `Pred` should be modified only later when a successor is added 
(`addTransition` has non-const parameter).



Comment at: 
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:1309
+[Node, Note](PathSensitiveBugReport ) -> std::string {
+  if (Node->succ_size() > 1)
+return Note.str();

donat.nagy wrote:
> It's surprising to see this check inside the lambda, as its result does not 
> depend on `BR`. My best guess is that it's performed here because the 
> successors of `Node` will appear between the execution of the surrounding 
> code and the execution of this lambda.
> 
> However, CheckerContext.h line 69-70 claims that "checkers should not retain 
> the node in their state since the nodes might get invalidated." which would 
> imply that the captured `Node` might be invalid when the lambda is called.
This check is to decide if multiple cases could be applied, the same as if we 
count how many times this place in the loop is executed (add a transition for a 
case, constraints could be applied). This check is problematic because other 
checkers can apply state splits before this checker is executed or after it, in 
this way `StreamChecker` interferes with this code (it has a state split for 
success/failure cases of same function, and here we see only that a single case 
is applied on one branch). This is why this check is only used in the 
`EvalCallAsPure` case (theoretically still another checker can make a state 
split in PostCall before this where the same constraint is applied, then the 
problem occurs again).

I made a solution that does not have this check but has 2 case loops instead, 
but the mentioned problem (which exists when `if (Summary.getInvalidationKd() 
== EvalCallAsPure)` is not used) did not go away. And it may not work to search 
backwards for the first node with the same statement, because maybe not the 
first one is where a state split is done.

I only think that if this lambda is called with the saved node, that node is 
not invalid because it is part of a bug report call sequence.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153776: [clang][analyzer] Display notes in StdLibraryFunctionsChecker only if interesting

2023-06-26 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The note tag that was previously added in all cases when a standard function 
call
is found is displayed now only if the function call (return value) is 
"interesting".
This results in less unneeded notes but some of the previously good notes 
disappear
too. This is because interestingness is not always set as it should be.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153776

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -13,7 +13,6 @@
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
-  // stdargs-note@-1 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -22,7 +21,6 @@
   }
   rewind(F2);
   fclose(F2);
-  // stdargs-note@-1 {{call fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -59,7 +57,6 @@
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{call is successful}}
-  // stdargs-note@-2 {{call is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -68,7 +65,6 @@
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
   // stdargs-note@-1 {{call is successful}}
-  // stdargs-note@-2 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -107,7 +103,6 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -127,7 +122,6 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -151,7 +145,6 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
-  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -11,7 +11,6 @@
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
   // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
-  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -24,7 +23,6 @@
 void check_tmpfile(void) {
   FILE *F = tmpfile();
   // expected-note@-1{{'errno' may be undefined after successful call to 'tmpfile'}}
-  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -36,14 +34,12 @@
 
 void check_freopen(void) {
   FILE *F = tmpfile();
-  // expected-note@-1{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
 return;
   F = freopen("xxx", "w", F);
   // expected-note@-1{{'errno' may be undefined after successful call to 'freopen'}}
-  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -55,14 +51,12 @@
 
 void check_fclose(void) {
   FILE *F = tmpfile();
-  // expected-note@-1{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
 return;
   (void)fclose(F);
   // expected-note@-1{{'errno' may be undefined after successful call to 'fclose'}}
-  // expected-note@-2{{call is successful}}
   

[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-26 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 534487.
balazske added a comment.

Add note tag always if function is not evaluated as "pure".
Reformat the code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -7,11 +7,13 @@
 
 void check_note_at_correct_open(void) {
   FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   FILE *F2 = tmpfile();
+  // stdargs-note@-1 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -20,6 +22,7 @@
   }
   rewind(F2);
   fclose(F2);
+  // stdargs-note@-1 {{call fails}}
   rewind(F1);
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
@@ -27,6 +30,7 @@
 
 void check_note_fopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -37,11 +41,13 @@
 
 void check_note_freopen(void) {
   FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
 return;
   F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  // stdargs-note@-1 {{call is successful}}
   if (!F)
 // expected-note@-1 {{'F' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -52,6 +58,8 @@
 
 void check_note_leak_2(int c) {
   FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
+  // stdargs-note@-2 {{call is successful}}
   if (!F1)
 // expected-note@-1 {{'F1' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -59,6 +67,8 @@
 // expected-note@-4 {{Taking false branch}}
 return;
   FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  // stdargs-note@-1 {{call is successful}}
+  // stdargs-note@-2 {{call is successful}}
   if (!F2) {
 // expected-note@-1 {{'F2' is non-null}}
 // expected-note@-2 {{Taking false branch}}
@@ -84,6 +94,7 @@
 void check_track_null(void) {
   FILE *F;
   F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}}
+  // stdargs-note@-1 {{call fails}}
   if (F != NULL) {  // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}}
 fclose(F);
 return;
@@ -96,6 +107,7 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -115,6 +127,7 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   }
@@ -138,6 +151,7 @@
   FILE *F;
   char Buf[10];
   F = fopen("foo1.c", "r");
+  // stdargs-note@-1 {{call is successful}}
   if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
 return;
   int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -10,7 +10,8 @@
 
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
-  // expected-note@-1{{Assuming that function 'fopen' is successful, in this case the value 'errno' may be undefined after the call and should not be used}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
+  // expected-note@-2{{call is successful}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -22,7 +23,8 @@
 
 void check_tmpfile(void) {
   FILE *F = tmpfile();
-  // 

[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

In D152436#4438956 , @NoQ wrote:

> Uh-oh, looks like I'm not paying nearly enough attention to this discussion 
> (sorry about that!!)
>
> I'm somewhat skeptical of the decision made in D151225 
>  because the entire reason I originally 
> implemented `StdCLibraryFunctions` was to deal with false positives I was 
> seeing. It was really valuable even without the bug-finding part. So I really 
> wish we could find some way to keep bug-finding and modeling separate.
>
> I haven't read the entire discussion though, I need to catch up 

The problem was that modeling and report generation could not be separated 
correctly. Both are implemented in one class but are differently named checkers 
that should run in a specific order because dependency issues, this was not 
good. Other problem was that if the modeling checker runs first, it will apply 
state changes for pre and post conditions without generating a bug report even 
if a bug could be found in the previous state. The old state is then lost and 
other checkers will not find that bug. For example a case of null pointer 
argument to a function is always removed by the modeling part of the checker, 
even if this was a case when a bug report should be generated.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/test/Analysis/errno-stdlibraryfunctions-notes.c:17
   access("path", 0);
-  // expected-note@-1{{Assuming that function 'access' is successful, in this 
case the value 'errno' may be undefined after the call and should not be used}}
+  // expected-note@-1{{Assuming that the call fails}}
+  access("path", 0);

This is the type of note that looks not necessary and even confusing. It could 
be any case of failure or success, the failure is chosen. This does not matter 
for the end result but can be confusing for users (one may think that there is 
a connection to the found bug).



Comment at: clang/test/Analysis/std-c-library-functions-path-notes.c:72
+return 0;
+  int l = islower(c);
+  f = fileno(f1); // \

Here no note is shown. Probably because the summary of `islower` has cases 
without note, these notes should be added.



Comment at: clang/test/Analysis/stream-errno-note.c:24
 void check_tmpfile(void) {
   FILE *F = tmpfile();
+  // expected-note@-1{{'errno' may be undefined after successful call to 
'tmpfile'}}

At this place a note 'Assuming that the call is successful' should be 
displayed. But this is not working because `StreamChecker` is enabled. 
`StreamChecker` makes a state split before `StdCLibraryFunctionsChecker` for 
`tmpfile` failure and success, then in `StdCLibraryFunctionsChecker` the 
successor count is 1 and the note is not added. Probably the logic can be 
improved by finding the first node that belongs to the `CallEvent`. Or count 
how many cases are applied before adding the note tags.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153612/new/

https://reviews.llvm.org/D153612

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

For first experiment I have made patch D153612 
 that adds a `NoteTag` to "all" standard 
function calls.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153424: [clang][ASTImporter] Add import of CXXRewrittenBinaryOperator.

2023-06-23 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGdd639eb15aac: [clang][ASTImporter] Add import of 
CXXRewrittenBinaryOperator. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153424/new/

https://reviews.llvm.org/D153424

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/rbo.cpp
  clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/std-compare.h
  clang/test/ASTMerge/cxx-rewritten-binary-operator/test.cpp

Index: clang/test/ASTMerge/cxx-rewritten-binary-operator/test.cpp
===
--- /dev/null
+++ clang/test/ASTMerge/cxx-rewritten-binary-operator/test.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -std=c++20 -emit-pch -o %t.1.ast %S/Inputs/rbo.cpp
+// RUN: %clang_cc1 -std=c++20 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
+// CHECK-NOT: unsupported AST node
Index: clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/std-compare.h
===
--- /dev/null
+++ clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/std-compare.h
@@ -0,0 +1,307 @@
+#ifndef STD_COMPARE_H
+#define STD_COMPARE_H
+
+namespace std {
+inline namespace __1 {
+
+// exposition only
+enum class _EqResult : unsigned char {
+  __equal = 0,
+  __equiv = __equal,
+};
+
+enum class _OrdResult : signed char {
+  __less = -1,
+  __greater = 1
+};
+
+enum class _NCmpResult : signed char {
+  __unordered = -127
+};
+
+struct _CmpUnspecifiedType;
+using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
+
+class partial_ordering {
+  using _ValueT = signed char;
+  explicit constexpr partial_ordering(_EqResult __v) noexcept
+  : __value_(_ValueT(__v)) {}
+  explicit constexpr partial_ordering(_OrdResult __v) noexcept
+  : __value_(_ValueT(__v)) {}
+  explicit constexpr partial_ordering(_NCmpResult __v) noexcept
+  : __value_(_ValueT(__v)) {}
+
+  constexpr bool __is_ordered() const noexcept {
+return __value_ != _ValueT(_NCmpResult::__unordered);
+  }
+
+public:
+  // valid values
+  static const partial_ordering less;
+  static const partial_ordering equivalent;
+  static const partial_ordering greater;
+  static const partial_ordering unordered;
+
+  // comparisons
+  friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+
+  friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+
+  // test helper
+  constexpr bool test_eq(partial_ordering const ) const noexcept {
+return __value_ == other.__value_;
+  }
+
+private:
+  _ValueT __value_;
+};
+
+inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
+inline constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
+inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
+inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
+constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ == 0;
+}
+constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ < 0;
+}
+constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ <= 0;
+}
+constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ > 0;
+}
+constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ >= 0;
+}
+constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+  return __v.__is_ordered() && 0 == __v.__value_;

[PATCH] D153612: [clang][analyzer] Add and change NoteTags in StdLibraryFunctionsChecker.

2023-06-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Change 1: ErrnoChecker notes show only messages related to errno,
not to assumption of success or failure of functions.
Change 2: StdLibraryFunctionsChecker adds its own note about success
or failure of functions, and the errno related note, independently.
Change 3: Every modeled function in StdLibraryFunctionsChecker
should have a note tag message in all "cases". This is not implemented yet,
only for file (stream) related functions.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153612

Files:
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/stream-errno-note.c

Index: clang/test/Analysis/stream-errno-note.c
===
--- clang/test/Analysis/stream-errno-note.c
+++ clang/test/Analysis/stream-errno-note.c
@@ -10,7 +10,7 @@
 
 void check_fopen(void) {
   FILE *F = fopen("xxx", "r");
-  // expected-note@-1{{Assuming that function 'fopen' is successful, in this case the value 'errno' may be undefined after the call and should not be used}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'fopen'}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -22,7 +22,7 @@
 
 void check_tmpfile(void) {
   FILE *F = tmpfile();
-  // expected-note@-1{{Assuming that function 'tmpfile' is successful, in this case the value 'errno' may be undefined after the call and should not be used}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'tmpfile'}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -39,7 +39,7 @@
   if (!F)
 return;
   F = freopen("xxx", "w", F);
-  // expected-note@-1{{Assuming that function 'freopen' is successful}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'freopen'}}
   // expected-note@+2{{'F' is non-null}}
   // expected-note@+1{{Taking false branch}}
   if (!F)
@@ -56,7 +56,7 @@
   if (!F)
 return;
   (void)fclose(F);
-  // expected-note@-1{{Assuming that function 'fclose' is successful}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'fclose'}}
   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
   // expected-note@-1{{An undefined value may be read from 'errno'}}
 }
@@ -69,7 +69,7 @@
   if (!F)
 return;
   (void)fread(Buf, 1, 10, F);
-  // expected-note@-1{{Assuming that function 'fread' is successful}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'fread'}}
   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
   // expected-note@-1{{An undefined value may be read from 'errno'}}
   (void)fclose(F);
@@ -83,7 +83,7 @@
   if (!F)
 return;
   int R = fwrite(Buf, 1, 10, F);
-  // expected-note@-1{{Assuming that function 'fwrite' is successful}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'fwrite'}}
   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
   // expected-note@-1{{An undefined value may be read from 'errno'}}
   (void)fclose(F);
@@ -96,7 +96,7 @@
   if (!F)
 return;
   (void)fseek(F, 11, SEEK_SET);
-  // expected-note@-1{{Assuming that function 'fseek' is successful}}
+  // expected-note@-1{{'errno' may be undefined after successful call to 'fseek'}}
   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
   // expected-note@-1{{An undefined value may be read from 'errno'}}
   (void)fclose(F);
@@ -109,7 +109,7 @@
   if (!F)
 return;
   errno = 0;
-  rewind(F); // expected-note{{Function 'rewind' indicates failure only by setting of 'errno'}}
+  rewind(F); // expected-note{{'rewind' indicates failure only by setting 'errno'}}
   fclose(F); // expected-warning{{Value of 'errno' was not checked and may be overwritten by function 'fclose' [alpha.unix.Errno]}}
   // expected-note@-1{{Value of 'errno' was not checked and may be overwritten by function 'fclose'}}
 }
@@ -121,7 +121,8 @@
   if (!F)
 return;
   fileno(F);
-  // expected-note@-1{{Assuming that function 'fileno' is successful}}
+  // expected-note@-1{{Assuming that the call is successful}}
+  // 

[PATCH] D153424: [clang][ASTImporter] Add import of CXXRewrittenBinaryOperator.

2023-06-22 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: 
clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/std-compare.h:307
+
+#endif // STD_COMPARE_H

I do not like to add this file but could not find a better solution. The file 
is copied from other test, this file has already multiple copies in the tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153424/new/

https://reviews.llvm.org/D153424

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153424: [clang][ASTImporter] Add import of CXXRewrittenBinaryOperator.

2023-06-21 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, martong, gamesh411, Szelethus, dkrupp.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153424

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/rbo.cpp
  clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/std-compare.h
  clang/test/ASTMerge/cxx-rewritten-binary-operator/test.cpp

Index: clang/test/ASTMerge/cxx-rewritten-binary-operator/test.cpp
===
--- /dev/null
+++ clang/test/ASTMerge/cxx-rewritten-binary-operator/test.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -std=c++20 -emit-pch -o %t.1.ast %S/Inputs/rbo.cpp
+// RUN: %clang_cc1 -std=c++20 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
+// CHECK-NOT: unsupported AST node
Index: clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/std-compare.h
===
--- /dev/null
+++ clang/test/ASTMerge/cxx-rewritten-binary-operator/Inputs/std-compare.h
@@ -0,0 +1,307 @@
+#ifndef STD_COMPARE_H
+#define STD_COMPARE_H
+
+namespace std {
+inline namespace __1 {
+
+// exposition only
+enum class _EqResult : unsigned char {
+  __equal = 0,
+  __equiv = __equal,
+};
+
+enum class _OrdResult : signed char {
+  __less = -1,
+  __greater = 1
+};
+
+enum class _NCmpResult : signed char {
+  __unordered = -127
+};
+
+struct _CmpUnspecifiedType;
+using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
+
+class partial_ordering {
+  using _ValueT = signed char;
+  explicit constexpr partial_ordering(_EqResult __v) noexcept
+  : __value_(_ValueT(__v)) {}
+  explicit constexpr partial_ordering(_OrdResult __v) noexcept
+  : __value_(_ValueT(__v)) {}
+  explicit constexpr partial_ordering(_NCmpResult __v) noexcept
+  : __value_(_ValueT(__v)) {}
+
+  constexpr bool __is_ordered() const noexcept {
+return __value_ != _ValueT(_NCmpResult::__unordered);
+  }
+
+public:
+  // valid values
+  static const partial_ordering less;
+  static const partial_ordering equivalent;
+  static const partial_ordering greater;
+  static const partial_ordering unordered;
+
+  // comparisons
+  friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+  friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+
+  friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+  friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+
+  // test helper
+  constexpr bool test_eq(partial_ordering const ) const noexcept {
+return __value_ == other.__value_;
+  }
+
+private:
+  _ValueT __value_;
+};
+
+inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
+inline constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
+inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
+inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
+constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ == 0;
+}
+constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ < 0;
+}
+constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ <= 0;
+}
+constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ > 0;
+}
+constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+  return __v.__is_ordered() && __v.__value_ >= 0;
+}
+constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) 

[PATCH] D153363: [clang][analyzer] No end-of-file when seek to file begin.

2023-06-21 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

This case 

 is an example of what can be fixed by the change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153363/new/

https://reviews.llvm.org/D153363

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153363: [clang][analyzer] No end-of-file when seek to file begin.

2023-06-20 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If `fseek` is used with 0 position and SEEK_SET it sets the position
to the start of the file. This should not cause FEOF (end of file) error.
The case of an empty file is not handled for simplification.
It is not exactly defined in what cases `fseek` produces the different
error states. Normally feof should not happen at all because it is
possible to set the position after the end of file, but previous tests
showed that still feof (and any other error cases) can happen.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153363

Files:
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/stream-error.c

Index: clang/test/Analysis/stream-error.c
===
--- clang/test/Analysis/stream-error.c
+++ clang/test/Analysis/stream-error.c
@@ -146,7 +146,7 @@
   FILE *F = fopen("file", "r");
   if (!F)
 return;
-  int rc = fseek(F, 0, SEEK_SET);
+  int rc = fseek(F, 1, SEEK_SET);
   if (rc) {
 int IsFEof = feof(F), IsFError = ferror(F);
 // Get feof or ferror or no error.
@@ -173,6 +173,35 @@
   fclose(F);
 }
 
+void error_fseek_0(void) {
+  FILE *F = fopen("file", "r");
+  if (!F)
+return;
+  int rc = fseek(F, 0, SEEK_SET);
+  if (rc) {
+int IsFEof = feof(F), IsFError = ferror(F);
+// Get ferror or no error, but not feof.
+clang_analyzer_eval(IsFError);
+// expected-warning@-1 {{FALSE}}
+// expected-warning@-2 {{TRUE}}
+clang_analyzer_eval(IsFEof);
+// expected-warning@-1 {{FALSE}}
+// Error flags should not change.
+clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
+if (IsFError)
+  clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}}
+else
+  clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
+  } else {
+clang_analyzer_eval(feof(F));   // expected-warning {{FALSE}}
+clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
+// Error flags should not change.
+clang_analyzer_eval(feof(F));   // expected-warning {{FALSE}}
+clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
+  }
+  fclose(F);
+}
+
 void error_indeterminate(void) {
   FILE *F = fopen("file", "r+");
   if (!F)
Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -285,7 +285,14 @@
 0}},
   };
 
+  /// Expanded value of EOF, empty before initialization.
   mutable std::optional EofVal;
+  /// Expanded value of SEEK_SET, 0 if not found.
+  mutable int SeekSetVal = 0;
+  /// Expanded value of SEEK_CUR, 1 if not found.
+  mutable int SeekCurVal = 1;
+  /// Expanded value of SEEK_END, 2 if not found.
+  mutable int SeekEndVal = 2;
 
   void evalFopen(const FnDescription *Desc, const CallEvent ,
  CheckerContext ) const;
@@ -432,7 +439,7 @@
 });
   }
 
-  void initEof(CheckerContext ) const {
+  void initMacroValues(CheckerContext ) const {
 if (EofVal)
   return;
 
@@ -441,6 +448,15 @@
   EofVal = *OptInt;
 else
   EofVal = -1;
+if (const std::optional OptInt =
+tryExpandAsInteger("SEEK_SET", C.getPreprocessor()))
+  SeekSetVal = *OptInt;
+if (const std::optional OptInt =
+tryExpandAsInteger("SEEK_END", C.getPreprocessor()))
+  SeekEndVal = *OptInt;
+if (const std::optional OptInt =
+tryExpandAsInteger("SEEK_CUR", C.getPreprocessor()))
+  SeekCurVal = *OptInt;
   }
 
   /// Searches for the ExplodedNode where the file descriptor was acquired for
@@ -488,7 +504,7 @@
 
 void StreamChecker::checkPreCall(const CallEvent ,
  CheckerContext ) const {
-  initEof(C);
+  initMacroValues(C);
 
   const FnDescription *Desc = lookupFn(Call);
   if (!Desc || !Desc->PreFn)
@@ -786,6 +802,11 @@
   if (!State->get(StreamSym))
 return;
 
+  const llvm::APSInt *PosV =
+  C.getSValBuilder().getKnownValue(State, Call.getArgSVal(1));
+  const llvm::APSInt *WhenceV =
+  C.getSValBuilder().getKnownValue(State, Call.getArgSVal(2));
+
   DefinedSVal RetVal = makeRetVal(C, CE);
 
   // Make expression result.
@@ -804,9 +825,12 @@
   // It is possible that fseek fails but sets none of the error flags.
   // If fseek failed, assume that the file position becomes indeterminate in any
   // case.
+  StreamErrorState NewErrS = ErrorNone | ErrorFError;
+  // Setting the position to start of file never produces EOF 

[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-19 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

It is possible to add note tags to show decisions at standard functions. For 
example at `fileno` show if it has failed or not failed. The most simple way is 
to add it to all places, this means a note will show up on any bug path at all 
standard function usages. This is how it works already with the existing notes. 
Like in the following code:

  int __test_case_note();
  
  int test_case_note_1(int y) {
int x1 = __test_case_note(); // expected-note{{Function returns 1}}
int x = __test_case_note(); // expected-note{{Function returns 0}} \
// expected-note{{'x' initialized here}}
return y / x; // expected-warning{{Division by zero}} \
  // expected-note{{Division by zero}}
  }
  
  int test_case_note_2(int y) {
int x = __test_case_note(); // expected-note{{Function returns 1}}
return y / (x - 1); // expected-warning{{Division by zero}} \
// expected-note{{Division by zero}}
  }

Here the first note at line with "x1" is not necessary. This problem can be 
fixed if the note is only shown when the return value is "interesting":

  int __test_case_note();
  
  int test_case_note_1(int y) {
int x1 = __test_case_note(); // no note
int x = __test_case_note(); // expected-note{{Function returns 0}} \
// expected-note{{'x' initialized here}}
return y / x; // expected-warning{{Division by zero}} \
  // expected-note{{Division by zero}}
  }
  
  int test_case_note_2(int y) {
int x = __test_case_note(); // no note
return y / (x - 1); // expected-warning{{Division by zero}} \
// expected-note{{Division by zero}}
  }

But in this case the note at `test_case_note_2` disappears because `x-1` is 
interesting, but not `x`. Fixing this problem looks more difficult.

From these two solutions, which one is better? (Show many unnecessary notes, or 
show only necessary ones but lose some of the useful notes too.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-09 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

In D152436#4408301 , @steakhal wrote:

> In D152436#4405558 , @balazske 
> wrote:
>
>> These are reports that could be improved:
>> link 
>> 
>> In this case function `fileno` returns -1 because of failure, but this is 
>> not indicated in a `NoteTag`. This is a correct result, only the note is 
>> missing. This problem can be solved if a note is displayed on every branch 
>> ("case") of the standard C functions. But this leads to many notes at 
>> un-interesting places. If the note is displayed only at "interesting" values 
>> another difficulty shows up: The note disappears from places where it should 
>> be shown because the "interestingness" is not set, for example at conditions 
>> of `if` statement. So the solution may require more work. This case with 
>> function `fileno` occurs 13 times in all the tested projects.
>
> Could you elaborate on what do you mean by "The note disappears from places 
> where it should be shown because the "interestingness" is not set, for 
> example at conditions of `if` statement.".  A short example would do the job 
> I think.
>
> I looked at the TPs, and if the violation was introduced by an assumption 
> (instead of an assignment), then it's really hard to spot which assumption is 
> important for the bug.
> I wonder if we could add the `TrackConstraintBRVisitor` to the bugreport to 
> "highlight" that particular assumption/place.

The question is first if this problem must be fixed before the checker comes 
out of alpha state. If yes I try to make another patch with this fix. I tried 
this previously but do not remember exactly what the problem was.




Comment at: clang/docs/analyzer/checkers.rst:922
+
+unix.StdCLibraryFunctions (C)
+"

This is applicable to C++ too?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-08 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

Another question is if default value of `ModelPOSIX` can be changed to true?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-08 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

One deficiency is that some filenames of test files contain the old 
**std-c-library-functions-arg** name that is not used any more.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-08 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

I could test the checker on these projects (CTU analysis was not used):
memcached,tmux,curl,twin,vim,openssl,sqlite,ffmpeg,postgres,tinyxml2,libwebm,xerces,bitcoin,protobuf,qtbase,contour,acid

These are reports that could be improved:
link 

In this case function `fileno` returns -1 because of failure, but this is not 
indicated in a `NoteTag`. This is a correct result, only the note is missing. 
This problem can be solved if a note is displayed on every branch ("case") of 
the standard C functions. But this leads to many notes at un-interesting 
places. If the note is displayed only at "interesting" values another 
difficulty shows up: The note disappears from places where it should be shown 
because the "interestingness" is not set, for example at conditions of `if` 
statement. So the solution may require more work. This case with function 
`fileno` occurs 13 times in all the tested projects.
link 

The function `open` is not modeled in `StdCLibraryFunctionsChecker`, it should 
not return less than -1 but this information is not included now.
link 

This looks wrong, `L` should not be 0 because `len` looks > 0 (see the macros 
that set `len`). Probably the many bitwise operations cause the problem.
link 

`socket` can not return less than -1 but this function is not modeled currently.
link 

`fwrite` with 0 buffer and 0 size should not be an error, this is not checked 
now.
link 

When `file_size` is 0 `status.ok()` is probably false that is not correctly 
recognized (may work in CTU mode?).

These results look good:
link 

link 

link 

link 

link 

link 

link 

link 

In this last case it looks like that previous call to `ftell` returns -1, this 
value is assigned to `fileSize`. This is again a case for improvement similar 
as the case with `fileno`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152436/new/

https://reviews.llvm.org/D152436

___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D152436: [clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha.

2023-06-08 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This checker can be good enough to move out of alpha.
I am not sure about the exact requirements, this review can be a place
for discussion about what should be fixed (if any).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152436

Files:
  clang/docs/analyzer/checkers.rst
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/test/Analysis/PR49642.c
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/analyzer-enabled-checkers.c
  clang/test/Analysis/conversion.c
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/errno-stdlibraryfunctions.c
  clang/test/Analysis/std-c-library-functions-POSIX-lookup.c
  clang/test/Analysis/std-c-library-functions-POSIX-socket-sockaddr.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
  clang/test/Analysis/std-c-library-functions-arg-cstring-dependency.c
  clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/Analysis/std-c-library-functions-eof.c
  clang/test/Analysis/std-c-library-functions-inlined.c
  clang/test/Analysis/std-c-library-functions-lookup.c
  clang/test/Analysis/std-c-library-functions-lookup.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/std-c-library-functions-restrict.c
  clang/test/Analysis/std-c-library-functions-restrict.cpp
  clang/test/Analysis/std-c-library-functions-vs-stream-checker.c
  clang/test/Analysis/std-c-library-functions.c
  clang/test/Analysis/std-c-library-functions.cpp
  clang/test/Analysis/std-c-library-posix-crash.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-errno.c
  clang/test/Analysis/stream-noopen.c
  clang/test/Analysis/stream-note.c
  clang/test/Analysis/stream-stdlibraryfunctionargs.c
  clang/test/Analysis/weak-dependencies.c

Index: clang/test/Analysis/weak-dependencies.c
===
--- clang/test/Analysis/weak-dependencies.c
+++ clang/test/Analysis/weak-dependencies.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 %s -verify \
-// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
+// RUN:   -analyzer-checker=unix.StdCLibraryFunctions \
 // RUN:   -analyzer-checker=core
 
 typedef __typeof(sizeof(int)) size_t;
Index: clang/test/Analysis/stream-stdlibraryfunctionargs.c
===
--- clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -1,11 +1,11 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
+// RUN:   -verify=stream,any %s
 
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdfunc,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdfunc,any %s
 
 #include "Inputs/system-header-simulator.h"
 
Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -analyzer-output text \
 // RUN:   -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions -analyzer-output text \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true 

[PATCH] D152169: [clang][analyzer] Add report of NULL stream to StreamChecker.

2023-06-06 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2c60f9c8a4fd: [clang][analyzer] Add report of NULL stream to 
StreamChecker. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152169/new/

https://reviews.llvm.org/D152169

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/Analysis/stream-note.c
  clang/test/Analysis/stream-stdlibraryfunctionargs.c
  clang/test/Analysis/stream.c

Index: clang/test/Analysis/stream.c
===
--- clang/test/Analysis/stream.c
+++ clang/test/Analysis/stream.c
@@ -2,6 +2,81 @@
 
 #include "Inputs/system-header-simulator.h"
 
+void check_fread(void) {
+  FILE *fp = tmpfile();
+  fread(0, 0, 0, fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fwrite(void) {
+  FILE *fp = tmpfile();
+  fwrite(0, 0, 0, fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fseek(void) {
+  FILE *fp = tmpfile();
+  fseek(fp, 0, 0); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_ftell(void) {
+  FILE *fp = tmpfile();
+  ftell(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_rewind(void) {
+  FILE *fp = tmpfile();
+  rewind(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fgetpos(void) {
+  FILE *fp = tmpfile();
+  fpos_t pos;
+  fgetpos(fp, ); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fsetpos(void) {
+  FILE *fp = tmpfile();
+  fpos_t pos;
+  fsetpos(fp, ); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_clearerr(void) {
+  FILE *fp = tmpfile();
+  clearerr(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_feof(void) {
+  FILE *fp = tmpfile();
+  feof(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_ferror(void) {
+  FILE *fp = tmpfile();
+  ferror(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fileno(void) {
+  FILE *fp = tmpfile();
+  fileno(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void f_open(void) {
+  FILE *p = fopen("foo", "r");
+  char buf[1024];
+  fread(buf, 1, 1, p); // expected-warning {{Stream pointer might be NULL}}
+  fclose(p);
+}
+
 void f_seek(void) {
   FILE *p = fopen("foo", "r");
   if (!p)
@@ -86,7 +161,7 @@
 }
 
 void check_freopen_1(void) {
-  FILE *f1 = freopen("foo.c", "r", (FILE *)0); // Not reported by the stream checker.
+  FILE *f1 = freopen("foo.c", "r", (FILE *)0); // expected-warning {{Stream pointer might be NULL}}
   f1 = freopen(0, "w", (FILE *)0x123456);  // Do not report this as error.
 }
 
Index: clang/test/Analysis/stream-stdlibraryfunctionargs.c
===
--- clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -1,11 +1,11 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdfunc,any %s
 
 #include "Inputs/system-header-simulator.h"
 
@@ -18,31 +18,43 @@
 void test_fopen(void) {
   FILE *fp = fopen("path", "r");
   clang_analyzer_eval(fp != NULL); // any-warning{{TRUE}} any-warning{{FALSE}}
-  fclose(fp); // stdargs-warning{{should not be NULL}}
+  fclose(fp); // \
+  // stream-warning{{Stream pointer might be NULL}} \
+  // stdfunc-warning{{should not be NULL}}
 }
 
 void test_tmpfile(void) {
   FILE *fp = tmpfile();
   clang_analyzer_eval(fp != NULL); // any-warning{{TRUE}} any-warning{{FALSE}}
-  fclose(fp); // stdargs-warning{{should not be NULL}}
+  fclose(fp); // \
+  // stream-warning{{Stream pointer might be NULL}} \
+  // stdfunc-warning{{should not be NULL}}
 }
 
 void test_fclose(void) {
   FILE 

[PATCH] D152169: [clang][analyzer] Add report of NULL stream to StreamChecker.

2023-06-05 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td:553
   HelpText<"Check stream handling functions">,
+  WeakDependencies<[NonNullParamChecker]>,
   Documentation;

steakhal wrote:
> What's the purpose of this hunk?
The intent was that `NonNullParamChecker` should find a null pointer problem 
before `StreamChecker` and have a fixed priority of the warnings. But 
NonNullParamChecker probably does not apply to the stream functions because 
there are no nonnull attributes (this may be possible?) and no references. No 
tests fail if this line is removed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152169/new/

https://reviews.llvm.org/D152169

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152169: [clang][analyzer] Add report of NULL stream to StreamChecker.

2023-06-05 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The report of NULL stream was removed in commit 570bf97 
.
The old reason is not actual any more because the checker dependencies are 
changed.
It is not good to eliminate a failure state (where the stream is NULL) without
generating a bug report because other checkers are not able to find it later.
The checker did this with the NULL stream pointer, and because this checker
runs now before other checkers that can detect NULL pointers, the null pointer
bug was not found at all.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152169

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/Analysis/stream-note.c
  clang/test/Analysis/stream-stdlibraryfunctionargs.c
  clang/test/Analysis/stream.c

Index: clang/test/Analysis/stream.c
===
--- clang/test/Analysis/stream.c
+++ clang/test/Analysis/stream.c
@@ -2,6 +2,81 @@
 
 #include "Inputs/system-header-simulator.h"
 
+void check_fread(void) {
+  FILE *fp = tmpfile();
+  fread(0, 0, 0, fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fwrite(void) {
+  FILE *fp = tmpfile();
+  fwrite(0, 0, 0, fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fseek(void) {
+  FILE *fp = tmpfile();
+  fseek(fp, 0, 0); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_ftell(void) {
+  FILE *fp = tmpfile();
+  ftell(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_rewind(void) {
+  FILE *fp = tmpfile();
+  rewind(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fgetpos(void) {
+  FILE *fp = tmpfile();
+  fpos_t pos;
+  fgetpos(fp, ); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fsetpos(void) {
+  FILE *fp = tmpfile();
+  fpos_t pos;
+  fsetpos(fp, ); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_clearerr(void) {
+  FILE *fp = tmpfile();
+  clearerr(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_feof(void) {
+  FILE *fp = tmpfile();
+  feof(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_ferror(void) {
+  FILE *fp = tmpfile();
+  ferror(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void check_fileno(void) {
+  FILE *fp = tmpfile();
+  fileno(fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
+void f_open(void) {
+  FILE *p = fopen("foo", "r");
+  char buf[1024];
+  fread(buf, 1, 1, p); // expected-warning {{Stream pointer might be NULL}}
+  fclose(p);
+}
+
 void f_seek(void) {
   FILE *p = fopen("foo", "r");
   if (!p)
@@ -86,7 +161,7 @@
 }
 
 void check_freopen_1(void) {
-  FILE *f1 = freopen("foo.c", "r", (FILE *)0); // Not reported by the stream checker.
+  FILE *f1 = freopen("foo.c", "r", (FILE *)0); // expected-warning {{Stream pointer might be NULL}}
   f1 = freopen(0, "w", (FILE *)0x123456);  // Do not report this as error.
 }
 
Index: clang/test/Analysis/stream-stdlibraryfunctionargs.c
===
--- clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -1,11 +1,11 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stream,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
-// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdfunc,any %s
 
 #include 

[PATCH] D151225: [clang][analyzer] Merge apiModeling.StdCLibraryFunctions and StdCLibraryFunctionArgs checkers into one.

2023-06-01 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4f0436dd1532: [clang][analyzer] Merge 
apiModeling.StdCLibraryFunctions and… (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151225/new/

https://reviews.llvm.org/D151225

Files:
  clang/docs/analyzer/checkers.rst
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/PR49642.c
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/analyzer-enabled-checkers.c
  clang/test/Analysis/conversion.c
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/errno-stdlibraryfunctions.c
  clang/test/Analysis/std-c-library-functions-POSIX-lookup.c
  clang/test/Analysis/std-c-library-functions-POSIX-socket-sockaddr.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
  clang/test/Analysis/std-c-library-functions-arg-cstring-dependency.c
  clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/Analysis/std-c-library-functions-eof.c
  clang/test/Analysis/std-c-library-functions-inlined.c
  clang/test/Analysis/std-c-library-functions-lookup.c
  clang/test/Analysis/std-c-library-functions-lookup.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/std-c-library-functions-restrict.c
  clang/test/Analysis/std-c-library-functions-restrict.cpp
  clang/test/Analysis/std-c-library-functions-vs-stream-checker.c
  clang/test/Analysis/std-c-library-functions.c
  clang/test/Analysis/std-c-library-functions.cpp
  clang/test/Analysis/std-c-library-posix-crash.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-errno.c
  clang/test/Analysis/stream-noopen.c
  clang/test/Analysis/stream-note.c
  clang/test/Analysis/stream-stdlibraryfunctionargs.c
  clang/test/Analysis/weak-dependencies.c

Index: clang/test/Analysis/weak-dependencies.c
===
--- clang/test/Analysis/weak-dependencies.c
+++ clang/test/Analysis/weak-dependencies.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 %s -verify \
-// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
+// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
 // RUN:   -analyzer-checker=core
 
 typedef __typeof(sizeof(int)) size_t;
Index: clang/test/Analysis/stream-stdlibraryfunctionargs.c
===
--- clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -1,11 +1,11 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctionArgs,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
 
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctionArgs,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
 
 #include "Inputs/system-header-simulator.h"
 
Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -analyzer-output text \
 // RUN:   -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctionArgs -analyzer-output text \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=expected,stdargs %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions -analyzer-output text \
+// RUN:   -analyzer-config 

[PATCH] D151431: [clang-tidy] Add check bugprone-unique-ptr-array-mismatch.

2023-05-31 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb0bab14b8b53: [clang-tidy] Add check 
bugprone-unique-ptr-array-mismatch. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151431/new/

https://reviews.llvm.org/D151431

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone/unique-ptr-array-mismatch.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
@@ -0,0 +1,127 @@
+// RUN: %check_clang_tidy %s bugprone-unique-ptr-array-mismatch %t
+
+namespace std {
+
+template struct default_delete {};
+template struct default_delete {};
+
+template>
+class unique_ptr {
+public:
+  explicit unique_ptr(T* p) noexcept;
+  unique_ptr(T* p, Deleter d1 ) noexcept;
+};
+
+template 
+class unique_ptr {
+public:
+  template
+  explicit unique_ptr(U p) noexcept;
+  template
+  unique_ptr(U p, Deleter d1) noexcept;
+};
+
+} // namespace std
+
+struct A {};
+
+using PtrT = std::unique_ptr;
+using PtrTArr = std::unique_ptr;
+
+void f1() {
+  std::unique_ptr P1{new int};
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2{new int[10]};
+  // clang-format off
+  std::unique_ptr<  int  > P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr<  int[]  > P3{new int[10]};
+  // clang-format on
+  std::unique_ptr P4(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P4(new int[10]);
+  new std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P5(new int[10]);
+
+  A deleter;
+  std::unique_ptr P6(new int[10], deleter);
+  std::unique_ptr P7(new int[10]);
+  std::default_delete def_del;
+  std::unique_ptr> P8(new int[10], def_del);
+
+  new PtrT(new A[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  new PtrTArr(new A[10]);
+}
+
+void f2() {
+  std::unique_ptr P1(new A);
+  std::unique_ptr P2(new A[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2(new A[10]);
+  std::unique_ptr P3(new A[10]);
+}
+
+void f3() {
+  std::unique_ptr P1{new int}, P2{new int[10]}, P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-MESSAGES: :[[@LINE-2]]:57: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+struct S {
+  std::unique_ptr P1;
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P3{new int}, P4{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  S() : P1{new int[10]} {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+};
+
+void f_parm(std::unique_ptr);
+
+void f4() {
+  f_parm(std::unique_ptr{new int[10]});
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+std::unique_ptr f_ret() {
+  return std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+template 
+void f_tmpl() {
+  std::unique_ptr P1{new T[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P1{new T[10]};
+}
+
+void 

[PATCH] D151431: [clang-tidy] Add check bugprone-unique-ptr-array-mismatch.

2023-05-31 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 526927.
balazske added a comment.

removed check name in documentation code comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151431/new/

https://reviews.llvm.org/D151431

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone/unique-ptr-array-mismatch.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
@@ -0,0 +1,127 @@
+// RUN: %check_clang_tidy %s bugprone-unique-ptr-array-mismatch %t
+
+namespace std {
+
+template struct default_delete {};
+template struct default_delete {};
+
+template>
+class unique_ptr {
+public:
+  explicit unique_ptr(T* p) noexcept;
+  unique_ptr(T* p, Deleter d1 ) noexcept;
+};
+
+template 
+class unique_ptr {
+public:
+  template
+  explicit unique_ptr(U p) noexcept;
+  template
+  unique_ptr(U p, Deleter d1) noexcept;
+};
+
+} // namespace std
+
+struct A {};
+
+using PtrT = std::unique_ptr;
+using PtrTArr = std::unique_ptr;
+
+void f1() {
+  std::unique_ptr P1{new int};
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2{new int[10]};
+  // clang-format off
+  std::unique_ptr<  int  > P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr<  int[]  > P3{new int[10]};
+  // clang-format on
+  std::unique_ptr P4(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P4(new int[10]);
+  new std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P5(new int[10]);
+
+  A deleter;
+  std::unique_ptr P6(new int[10], deleter);
+  std::unique_ptr P7(new int[10]);
+  std::default_delete def_del;
+  std::unique_ptr> P8(new int[10], def_del);
+
+  new PtrT(new A[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  new PtrTArr(new A[10]);
+}
+
+void f2() {
+  std::unique_ptr P1(new A);
+  std::unique_ptr P2(new A[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2(new A[10]);
+  std::unique_ptr P3(new A[10]);
+}
+
+void f3() {
+  std::unique_ptr P1{new int}, P2{new int[10]}, P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-MESSAGES: :[[@LINE-2]]:57: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+struct S {
+  std::unique_ptr P1;
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P3{new int}, P4{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  S() : P1{new int[10]} {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+};
+
+void f_parm(std::unique_ptr);
+
+void f4() {
+  f_parm(std::unique_ptr{new int[10]});
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+std::unique_ptr f_ret() {
+  return std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+template 
+void f_tmpl() {
+  std::unique_ptr P1{new T[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P1{new T[10]};
+}
+
+void f5() {
+  f_tmpl();
+}
+
+template 
+void f_tmpl_1() {
+  

[PATCH] D151225: [clang][analyzer] Merge apiModeling.StdCLibraryFunctions and StdCLibraryFunctionArgs checkers into one.

2023-05-30 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

There are still some problems with dependencies, the `ErrnoChecker` really 
needs now the `StdCLibraryFunctions` checker (to be turned on and run before) 
but this is not enforced. The checker order looks to work but not enforced 
specially.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151225/new/

https://reviews.llvm.org/D151225

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D151225: [clang][analyzer] Merge apiModeling.StdCLibraryFunctions and StdCLibraryFunctionArgs checkers into one.

2023-05-30 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 526623.
balazske added a comment.

Updated documentation and removed occurrences of old checker name.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151225/new/

https://reviews.llvm.org/D151225

Files:
  clang/docs/analyzer/checkers.rst
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/PR49642.c
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/analyzer-enabled-checkers.c
  clang/test/Analysis/conversion.c
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/errno-stdlibraryfunctions.c
  clang/test/Analysis/std-c-library-functions-POSIX-lookup.c
  clang/test/Analysis/std-c-library-functions-POSIX-socket-sockaddr.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
  clang/test/Analysis/std-c-library-functions-arg-cstring-dependency.c
  clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/Analysis/std-c-library-functions-eof.c
  clang/test/Analysis/std-c-library-functions-inlined.c
  clang/test/Analysis/std-c-library-functions-lookup.c
  clang/test/Analysis/std-c-library-functions-lookup.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/std-c-library-functions-restrict.c
  clang/test/Analysis/std-c-library-functions-restrict.cpp
  clang/test/Analysis/std-c-library-functions-vs-stream-checker.c
  clang/test/Analysis/std-c-library-functions.c
  clang/test/Analysis/std-c-library-functions.cpp
  clang/test/Analysis/std-c-library-posix-crash.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-errno.c
  clang/test/Analysis/stream-noopen.c
  clang/test/Analysis/stream-note.c
  clang/test/Analysis/stream-stdlibraryfunctionargs.c
  clang/test/Analysis/weak-dependencies.c

Index: clang/test/Analysis/weak-dependencies.c
===
--- clang/test/Analysis/weak-dependencies.c
+++ clang/test/Analysis/weak-dependencies.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 %s -verify \
-// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
+// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
 // RUN:   -analyzer-checker=core
 
 typedef __typeof(sizeof(int)) size_t;
Index: clang/test/Analysis/stream-stdlibraryfunctionargs.c
===
--- clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -1,11 +1,11 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctionArgs,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
 
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctionArgs,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
 
 #include "Inputs/system-header-simulator.h"
 
Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -analyzer-output text \
 // RUN:   -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctionArgs -analyzer-output text \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=expected,stdargs %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions -analyzer-output text \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true 

[PATCH] D151431: [clang-tidy] Add check bugprone-unique-ptr-array-mismatch.

2023-05-26 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

The case of fully dependent type (`unique_ptr`) is not working in this 
checker and likely not in `SharedPtrArrayMismatchCheck`. I can fix this in a 
next patch (for both checkers).
Maybe we can remove the warning in all cases when the type is a POD type (or 
add a check option)?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151431/new/

https://reviews.llvm.org/D151431

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D151431: [clang-tidy] Add check bugprone-unique-ptr-array-mismatch.

2023-05-26 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 526063.
balazske marked an inline comment as done.
balazske added a comment.

Fixed the documentation issue.
Added tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151431/new/

https://reviews.llvm.org/D151431

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone/unique-ptr-array-mismatch.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
@@ -0,0 +1,127 @@
+// RUN: %check_clang_tidy %s bugprone-unique-ptr-array-mismatch %t
+
+namespace std {
+
+template struct default_delete {};
+template struct default_delete {};
+
+template>
+class unique_ptr {
+public:
+  explicit unique_ptr(T* p) noexcept;
+  unique_ptr(T* p, Deleter d1 ) noexcept;
+};
+
+template 
+class unique_ptr {
+public:
+  template
+  explicit unique_ptr(U p) noexcept;
+  template
+  unique_ptr(U p, Deleter d1) noexcept;
+};
+
+} // namespace std
+
+struct A {};
+
+using PtrT = std::unique_ptr;
+using PtrTArr = std::unique_ptr;
+
+void f1() {
+  std::unique_ptr P1{new int};
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2{new int[10]};
+  // clang-format off
+  std::unique_ptr<  int  > P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr<  int[]  > P3{new int[10]};
+  // clang-format on
+  std::unique_ptr P4(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P4(new int[10]);
+  new std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P5(new int[10]);
+
+  A deleter;
+  std::unique_ptr P6(new int[10], deleter);
+  std::unique_ptr P7(new int[10]);
+  std::default_delete def_del;
+  std::unique_ptr> P8(new int[10], def_del);
+
+  new PtrT(new A[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  new PtrTArr(new A[10]);
+}
+
+void f2() {
+  std::unique_ptr P1(new A);
+  std::unique_ptr P2(new A[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2(new A[10]);
+  std::unique_ptr P3(new A[10]);
+}
+
+void f3() {
+  std::unique_ptr P1{new int}, P2{new int[10]}, P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-MESSAGES: :[[@LINE-2]]:57: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+struct S {
+  std::unique_ptr P1;
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P3{new int}, P4{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  S() : P1{new int[10]} {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+};
+
+void f_parm(std::unique_ptr);
+
+void f4() {
+  f_parm(std::unique_ptr{new int[10]});
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+std::unique_ptr f_ret() {
+  return std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+template 
+void f_tmpl() {
+  std::unique_ptr P1{new T[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P1{new T[10]};
+}
+
+void f5() {
+  f_tmpl();
+}
+

[PATCH] D151431: [clang-tidy] Add check bugprone-unique-ptr-array-mismatch.

2023-05-25 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: PiotrZSL, carlosgalvezp, steakhal, martong, 
gamesh411, Szelethus, dkrupp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151431

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UniquePtrArrayMismatchCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone/unique-ptr-array-mismatch.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/unique-ptr-array-mismatch.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s bugprone-unique-ptr-array-mismatch %t
+
+namespace std {
+
+template struct default_delete;
+template struct default_delete;
+
+template>
+class unique_ptr {
+public:
+  explicit unique_ptr(T* p) noexcept;
+  unique_ptr(T* p, Deleter d1 ) noexcept;
+};
+
+template 
+class unique_ptr {
+public:
+  template
+  explicit unique_ptr(U p) noexcept;
+  template
+  unique_ptr(U p, Deleter d1) noexcept;
+};
+
+} // namespace std
+
+struct A {};
+
+void f1() {
+  std::unique_ptr P1{new int};
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2{new int[10]};
+  // clang-format off
+  std::unique_ptr<  int  > P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr<  int[]  > P3{new int[10]};
+  // clang-format on
+  std::unique_ptr P4(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P4(new int[10]);
+  new std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P5(new int[10]);
+  A deleter;
+  std::unique_ptr P6(new int[10], deleter);
+  std::unique_ptr P7(new int[10]);
+}
+
+void f2() {
+  std::unique_ptr P1(new A);
+  std::unique_ptr P2(new A[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P2(new A[10]);
+  std::unique_ptr P3(new A[10]);
+}
+
+void f3() {
+  std::unique_ptr P1{new int}, P2{new int[10]}, P3{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-MESSAGES: :[[@LINE-2]]:57: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+struct S {
+  std::unique_ptr P1;
+  std::unique_ptr P2{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  std::unique_ptr P3{new int}, P4{new int[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  S() : P1{new int[10]} {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+};
+
+void f_parm(std::unique_ptr);
+
+void f4() {
+  f_parm(std::unique_ptr{new int[10]});
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+std::unique_ptr f_ret() {
+  return std::unique_ptr(new int[10]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+}
+
+template 
+void f_tmpl() {
+  std::unique_ptr P1{new T[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unique pointer to non-array is initialized with array [bugprone-unique-ptr-array-mismatch]
+  // CHECK-FIXES: std::unique_ptr P1{new T[10]};
+}
+
+void f5() {
+  f_tmpl();
+}
+
+#define CHAR_PTR_TYPE std::unique_ptr
+#define CHAR_PTR_VAR(X) \
+  X { new char[10] }
+#define CHAR_PTR_INIT(X, Y) \
+  std::unique_ptr X { Y }
+
+void f6() {
+  CHAR_PTR_TYPE P1{new char[10]};
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: 

[PATCH] D151225: [clang][analyzer] Merge apiModeling.StdCLibraryFunctions and StdCLibraryFunctionArgs checkers into one.

2023-05-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a reviewer: NoQ.
Herald added a project: All.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Main reason for this change is that these checkers were implemented in the same 
class
but had different dependency ordering. (NonNullParamChecker should run before 
StdCLibraryFunctionArgs
to get more special warning about null arguments, but the 
apiModeling.StdCLibraryFunctions was a modeling
checker that should run before other non-modeling checkers. The modeling 
checker changes state in a way
that makes it impossible to detect a null argument by NonNullParamChecker.)
To make it more simple, the modeling part is removed as separate checker and 
can be only used if
checker StdCLibraryFunctions is turned on, that produces the warnings too. 
Modeling the functions
without bug detection (for invalid argument) is not possible. The modeling of 
standard functions
does not happen by default from this change on.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151225

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/PR49642.c
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/analyzer-enabled-checkers.c
  clang/test/Analysis/conversion.c
  clang/test/Analysis/errno-stdlibraryfunctions-notes.c
  clang/test/Analysis/errno-stdlibraryfunctions.c
  clang/test/Analysis/std-c-library-functions-POSIX-lookup.c
  clang/test/Analysis/std-c-library-functions-POSIX-socket-sockaddr.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c
  clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
  clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.c
  clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
  clang/test/Analysis/std-c-library-functions-arg-cstring-dependency.c
  clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/Analysis/std-c-library-functions-eof.c
  clang/test/Analysis/std-c-library-functions-inlined.c
  clang/test/Analysis/std-c-library-functions-lookup.c
  clang/test/Analysis/std-c-library-functions-lookup.cpp
  clang/test/Analysis/std-c-library-functions-path-notes.c
  clang/test/Analysis/std-c-library-functions-restrict.c
  clang/test/Analysis/std-c-library-functions-restrict.cpp
  clang/test/Analysis/std-c-library-functions-vs-stream-checker.c
  clang/test/Analysis/std-c-library-functions.c
  clang/test/Analysis/std-c-library-functions.cpp
  clang/test/Analysis/std-c-library-posix-crash.c
  clang/test/Analysis/stream-errno-note.c
  clang/test/Analysis/stream-errno.c
  clang/test/Analysis/stream-noopen.c
  clang/test/Analysis/stream-note.c
  clang/test/Analysis/stream-stdlibraryfunctionargs.c
  clang/test/Analysis/weak-dependencies.c

Index: clang/test/Analysis/weak-dependencies.c
===
--- clang/test/Analysis/weak-dependencies.c
+++ clang/test/Analysis/weak-dependencies.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 %s -verify \
-// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
+// RUN:   -analyzer-checker=alpha.unix.StdCLibraryFunctions \
 // RUN:   -analyzer-checker=core
 
 typedef __typeof(sizeof(int)) size_t;
Index: clang/test/Analysis/stream-stdlibraryfunctionargs.c
===
--- clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -1,11 +1,11 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctionArgs,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctions,debug.ExprInspection \
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
 
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
+// RUN:   -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true -verify=any %s
 
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.StdCLibraryFunctionArgs,debug.ExprInspection \
-// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=stdargs,any %s
+// RUN: 

[PATCH] D149447: [clang][analyzer] Improve documentation of StdCLibraryFunctionArgs checker (NFC)

2023-05-18 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4400ff587be2: [clang][analyzer] Improve documentation of 
StdCLibraryFunctionArgs checker (NFC) (authored by balazske).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149447/new/

https://reviews.llvm.org/D149447

Files:
  clang/docs/analyzer/checkers.rst

Index: clang/docs/analyzer/checkers.rst
===
--- clang/docs/analyzer/checkers.rst
+++ clang/docs/analyzer/checkers.rst
@@ -2432,17 +2432,57 @@
 
 .. code-block:: c
 
+  #define EOF -1
   void test_alnum_concrete(int v) {
 int ret = isalnum(256); // \
-// warning: Function argument constraint is not satisfied
+// warning: Function argument outside of allowed range
 (void)ret;
   }
 
-If the argument's value is unknown then the value is assumed to hold the proper value range.
+  void buffer_size_violation(FILE *file) {
+enum { BUFFER_SIZE = 1024 };
+wchar_t wbuf[BUFFER_SIZE];
+
+const size_t size = sizeof(*wbuf);   // 4
+const size_t nitems = sizeof(wbuf);  // 4096
+
+// Below we receive a warning because the 3rd parameter should be the
+// number of elements to read, not the size in bytes. This case is a known
+// vulnerability described by the ARR38-C SEI-CERT rule.
+fread(wbuf, size, nitems, file);
+  }
+
+You can think of this checker as defining restrictions (pre- and postconditions)
+on standard library functions. Preconditions are checked, and when they are
+violated, a warning is emitted. Post conditions are added to the analysis, e.g.
+that the return value must be no greater than 255.
+
+These are the possible checks on the values passed as function arguments:
+ - The argument has an allowed range (or multiple ranges) of values. The checker
+   can detect if a passed value is outside of the allowed range and show the
+   actual and allowed values.
+ - The argument has pointer type and is not allowed to be null pointer. Many
+   (but not all) standard functions can produce undefined behavior if a null
+   pointer is passed, these cases can be detected by the checker.
+ - The argument is a pointer to a memory block and the minimal size of this
+   buffer is determined by another argument to the function, or by
+   multiplication of two arguments (like at function ``fread``), or is a fixed
+   value (for example ``asctime_r`` requires at least a buffer of size 26). The
+   checker can detect if the buffer size is too small and in optimal case show
+   the size of the buffer and the values of the corresponding arguments.
+
+If the user disables the checker then the argument violation warning is
+suppressed. However, the assumption about the argument is still modeled.
+For instance, if the argument to a function must be in between 0 and 255,
+but the value of the argument is unknown, the analyzer will conservatively
+assume that it is in this interval, even if warnings for this checker are
+disabled. Similarly, if a function mustn't be called with a null pointer but it
+is, analysis will stop on that execution path (similarly to a division by zero),
+with or without a warning. If the null value of the argument can not be proven,
+the analyzer will assume that it is non-null.
 
 .. code-block:: c
 
-  #define EOF -1
   int test_alnum_symbolic(int x) {
 int ret = isalnum(x);
 // after the call, ret is assumed to be in the range [-1, 255]
@@ -2453,55 +2493,27 @@
 return ret;
   }
 
-If the user disables the checker then the argument violation warning is
-suppressed. However, the assumption about the argument is still modeled. This
-is because exploring an execution path that already contains undefined behavior
-is not valuable.
-
-There are different kind of constraints modeled: range constraint, not null
-constraint, buffer size constraint. A **range constraint** requires the
-argument's value to be in a specific range, see ``isalnum`` as an example above.
-A **not null constraint** requires the pointer argument to be non-null.
-
-A **buffer size** constraint specifies the minimum size of the buffer
-argument. The size might be a known constant. For example, ``asctime_r`` requires
-that the buffer argument's size must be greater than or equal to ``26`` bytes. In
-other cases, the size is denoted by another argument or as a multiplication of
-two arguments.
-For instance, ``size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)``.
-Here, ``ptr`` is the buffer, and its minimum size is ``size * nmemb``
-
-.. code-block:: c
-
-  void buffer_size_constraint_violation(FILE *file) {
-enum { BUFFER_SIZE = 1024 };
-wchar_t wbuf[BUFFER_SIZE];
-
-const size_t size = sizeof(*wbuf);   // 4
-const size_t nitems = sizeof(wbuf);  // 4096
-
-// Below we receive a warning because the 3rd parameter should be the
-// number of elements to read, not the size in bytes. This case is 

[PATCH] D149447: [clang][analyzer] Improve documentation of StdCLibraryFunctionArgs checker (NFC)

2023-05-18 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added inline comments.



Comment at: clang/docs/analyzer/checkers.rst:2490-2523
+**List of checked functions**
+
+``fgetc``, ``fread``, ``fwrite``, ``getc``, ``getchar``, ``getdelim``,
+``getenv``, ``getline``, ``isalnum``, ``isalpha``, ``isascii``, ``isblank``,
+``isdigit``, ``isgraph``, ``islower``, ``isprint``, ``ispunct``, ``isspace``,
+``isupper``, ``isxdigit``, ``read``, ``toascii``, ``tolower``, ``toupper``,
+``write``

Szelethus wrote:
> balazske wrote:
> > Szelethus wrote:
> > > We should create an option or something the //actual// list of functions 
> > > we model. This is the prime example of unsustainable documenting.
> > Such function lists are used at documentation of other checkers, but I am 
> > not sure if it is good to add such a long list here. Probably the 
> > "DisplayLoadedSummaries" option of `apiModeling.StdCLibraryFunctions` 
> > checker can be used, this lists only the actually found functions (that 
> > have available declaration and are enabled), and the console output needs 
> > to be observed to see the list. And this option is currently not documented.
> > Such function lists are used at documentation of other checkers
> 
> Is it possible that those lists are not really expected to change? We do 
> expect the list for this checker to grow, do we not?
At first look not all other checkers check every possible function, only the 
most common ones, it looks possible to extend these. Some have an incomplete 
list in the documentation. My concern was if an user want to know if a specific 
function is checked or not.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149447/new/

https://reviews.llvm.org/D149447

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   8   9   10   >