[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-06-14 Thread Balázs Benics via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGde6ba9704d0b: [analyzer][Casting] Support isa, cast, 
dyn_cast of SVals (authored by steakhal).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
  clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp


Index: clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -446,7 +446,7 @@
 
   // FIXME: We really should allow ranges of valid theType values, and
   //   bifurcate the state appropriately.
-  Optional V = TheTypeVal.getAs();
+  Optional V = dyn_cast(TheTypeVal);
   if (!V)
 return;
 
@@ -907,7 +907,7 @@
 
   // Go ahead and assume the value is non-nil.
   SVal Val = State->getSVal(*ElementLoc);
-  return State->assume(Val.castAs(), true);
+  return State->assume(cast(Val), true);
 }
 
 /// Returns NULL state if the collection is known to contain elements
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -98,19 +98,12 @@
 
   /// Convert to the specified SVal type, asserting that this SVal is of
   /// the desired type.
-  template
-  T castAs() const {
-assert(T::classof(*this));
-return *static_cast(this);
-  }
+  template  T castAs() const { return llvm::cast(*this); }
 
   /// Convert to the specified SVal type, returning None if this SVal is
   /// not of the desired type.
-  template
-  Optional getAs() const {
-if (!T::classof(*this))
-  return None;
-return *static_cast(this);
+  template  Optional getAs() const {
+return llvm::dyn_cast(*this);
   }
 
   unsigned getRawKind() const { return Kind; }
@@ -564,4 +557,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { return Optional{}; }
+  static To doCast(const From ) {
+return *static_cast(cast<::clang::ento::SVal>());
+  }
+  static Optional doCastIfPossible(const From ) {
+if (!Self::isPossible(f))
+  return Self::castFailed();
+return doCast(f);
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H


Index: clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -446,7 +446,7 @@
 
   // FIXME: We really should allow ranges of valid theType values, and
   //   bifurcate the state appropriately.
-  Optional V = TheTypeVal.getAs();
+  Optional V = dyn_cast(TheTypeVal);
   if (!V)
 return;
 
@@ -907,7 +907,7 @@
 
   // Go ahead and assume the value is non-nil.
   SVal Val = State->getSVal(*ElementLoc);
-  return State->assume(Val.castAs(), true);
+  return State->assume(cast(Val), true);
 }
 
 /// Returns NULL state if the collection is known to contain elements
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -98,19 +98,12 @@
 
   /// Convert to the specified SVal type, asserting that this SVal is of
   /// the desired type.
-  template
-  T castAs() const {
-assert(T::classof(*this));
-return *static_cast(this);
-  }
+  template  T castAs() const { return llvm::cast(*this); }
 
   /// Convert to the specified SVal type, returning None if this SVal is
   /// not of the desired type.
-  template
-  Optional getAs() const {
-if (!T::classof(*this))
-  return None;
-return *static_cast(this);
+  template  Optional getAs() const {
+return llvm::dyn_cast(*this);
   }
 
   unsigned getRawKind() const { return Kind; }
@@ -564,4 +557,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { 

[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-18 Thread Balázs Benics via Phabricator via cfe-commits
steakhal added a comment.

In D125709#3519850 , @xazax.hun wrote:

> While not having tests might be OK, but I'd prefer to introduce at least a 
> couple uses of the new facilities so existing tests cover them.

I've added a use of the new `dyn_cast` and `cast` free function specializations.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-18 Thread Balázs Benics via Phabricator via cfe-commits
steakhal updated this revision to Diff 430327.
steakhal added a comment.

- Added uses for `dyn_cast` and `cast` of the new specialization.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
  clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp


Index: clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -446,7 +446,7 @@
 
   // FIXME: We really should allow ranges of valid theType values, and
   //   bifurcate the state appropriately.
-  Optional V = TheTypeVal.getAs();
+  Optional V = dyn_cast(TheTypeVal);
   if (!V)
 return;
 
@@ -907,7 +907,7 @@
 
   // Go ahead and assume the value is non-nil.
   SVal Val = State->getSVal(*ElementLoc);
-  return State->assume(Val.castAs(), true);
+  return State->assume(cast(Val), true);
 }
 
 /// Returns NULL state if the collection is known to contain elements
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -98,19 +98,12 @@
 
   /// Convert to the specified SVal type, asserting that this SVal is of
   /// the desired type.
-  template
-  T castAs() const {
-assert(T::classof(*this));
-return *static_cast(this);
-  }
+  template  T castAs() const { return llvm::cast(*this); }
 
   /// Convert to the specified SVal type, returning None if this SVal is
   /// not of the desired type.
-  template
-  Optional getAs() const {
-if (!T::classof(*this))
-  return None;
-return *static_cast(this);
+  template  Optional getAs() const {
+return llvm::dyn_cast(*this);
   }
 
   unsigned getRawKind() const { return Kind; }
@@ -571,4 +564,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { return Optional{}; }
+  static To doCast(const From ) {
+return *static_cast(cast<::clang::ento::SVal>());
+  }
+  static Optional doCastIfPossible(const From ) {
+if (!Self::isPossible(f))
+  return Self::castFailed();
+return doCast(f);
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H


Index: clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -446,7 +446,7 @@
 
   // FIXME: We really should allow ranges of valid theType values, and
   //   bifurcate the state appropriately.
-  Optional V = TheTypeVal.getAs();
+  Optional V = dyn_cast(TheTypeVal);
   if (!V)
 return;
 
@@ -907,7 +907,7 @@
 
   // Go ahead and assume the value is non-nil.
   SVal Val = State->getSVal(*ElementLoc);
-  return State->assume(Val.castAs(), true);
+  return State->assume(cast(Val), true);
 }
 
 /// Returns NULL state if the collection is known to contain elements
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -98,19 +98,12 @@
 
   /// Convert to the specified SVal type, asserting that this SVal is of
   /// the desired type.
-  template
-  T castAs() const {
-assert(T::classof(*this));
-return *static_cast(this);
-  }
+  template  T castAs() const { return llvm::cast(*this); }
 
   /// Convert to the specified SVal type, returning None if this SVal is
   /// not of the desired type.
-  template
-  Optional getAs() const {
-if (!T::classof(*this))
-  return None;
-return *static_cast(this);
+  template  Optional getAs() const {
+return llvm::dyn_cast(*this);
   }
 
   unsigned getRawKind() const { return Kind; }
@@ -571,4 +564,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { return Optional{}; }
+  static To doCast(const From 

[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun added a comment.

While not having tests might be OK, but I'd prefer to introduce at least a 
couple uses of the new facilities so existing tests cover them.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Balázs Benics via Phabricator via cfe-commits
steakhal added a comment.

Thanks for your help @bzcheeseman!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Aman LaChapelle via Phabricator via cfe-commits
bzcheeseman accepted this revision.
bzcheeseman added a comment.
This revision is now accepted and ready to land.

> In D125709#3519033 , @bzcheeseman 
> wrote:
>
>> In D125709#3518096 , @steakhal 
>> wrote:
>>
>>> I had to fix the `doCast` to return `To` instead of `Optional` to make 
>>> it work.
>>
>> That's fine (or it should be!), you could dereference the optional if you 
>> wanted to
>
> Currently, we expect that casts result in regular SVal objects, instead of 
> pointer-like objects , thus this code to compile:
> `NonLoc N = llvm::cast(V)`, where `V` is of type `SVal`. I believe 
> that is why I decided to make that change.

Makes sense, LGTM


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Balázs Benics via Phabricator via cfe-commits
steakhal added a comment.

In D125709#3518242 , @martong wrote:

>> I'm not sure, shall I add tests?
>
> Yes, please. Unit tests for `dyn_cast` and `isa` should be easy. However, I 
> am not sure how to test `cast` for the failure cases.

What if we were using the 'new' casting style at some places. If it compiles, 
it should be fine.
It feels weird to check stuff, only in `static_asserts`.

In D125709#3519033 , @bzcheeseman 
wrote:

> In D125709#3518096 , @steakhal 
> wrote:
>
>> I had to fix the `doCast` to return `To` instead of `Optional` to make 
>> it work.
>
> That's fine (or it should be!), you could dereference the optional if you 
> wanted to

Currently, we expect that casts result in regular SVal objects, instead of 
pointer-like objects , thus this code to compile:
`NonLoc N = llvm::cast(V)`, where `V` is of type `SVal`. I believe that 
is why I decided to make that change.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Aman LaChapelle via Phabricator via cfe-commits
bzcheeseman added a comment.

In D125709#3518096 , @steakhal wrote:

> I had to fix the `doCast` to return `To` instead of `Optional` to make it 
> work.

That's fine (or it should be!) but you can also just dereference the optional, 
right?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

> I'm not sure, shall I add tests?

Yes, please. Unit tests for `dyn_cast` and `isa` should be easy. However, I am 
not sure how to test `cast` for the failure cases.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Balázs Benics via Phabricator via cfe-commits
steakhal marked an inline comment as done.
steakhal added a comment.

I had to fix the `doIt` to return `To` instead of `Optional` to make it 
work.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-17 Thread Balázs Benics via Phabricator via cfe-commits
steakhal updated this revision to Diff 429947.
steakhal added a comment.

Use `cast` and `dyn_cast` in `castAs` and `getAs` respecitvely.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h


Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -98,19 +98,12 @@
 
   /// Convert to the specified SVal type, asserting that this SVal is of
   /// the desired type.
-  template
-  T castAs() const {
-assert(T::classof(*this));
-return *static_cast(this);
-  }
+  template  T castAs() const { return llvm::cast(*this); }
 
   /// Convert to the specified SVal type, returning None if this SVal is
   /// not of the desired type.
-  template
-  Optional getAs() const {
-if (!T::classof(*this))
-  return None;
-return *static_cast(this);
+  template  Optional getAs() const {
+return llvm::dyn_cast(*this);
   }
 
   unsigned getRawKind() const { return Kind; }
@@ -571,4 +564,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { return Optional{}; }
+  static To doCast(const From ) {
+return *static_cast(cast<::clang::ento::SVal>());
+  }
+  static Optional doCastIfPossible(const From ) {
+if (!Self::isPossible(f))
+  return Self::castFailed();
+return doCast(f);
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H


Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -98,19 +98,12 @@
 
   /// Convert to the specified SVal type, asserting that this SVal is of
   /// the desired type.
-  template
-  T castAs() const {
-assert(T::classof(*this));
-return *static_cast(this);
-  }
+  template  T castAs() const { return llvm::cast(*this); }
 
   /// Convert to the specified SVal type, returning None if this SVal is
   /// not of the desired type.
-  template
-  Optional getAs() const {
-if (!T::classof(*this))
-  return None;
-return *static_cast(this);
+  template  Optional getAs() const {
+return llvm::dyn_cast(*this);
   }
 
   unsigned getRawKind() const { return Kind; }
@@ -571,4 +564,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { return Optional{}; }
+  static To doCast(const From ) {
+return *static_cast(cast<::clang::ento::SVal>());
+  }
+  static Optional doCastIfPossible(const From ) {
+if (!Self::isPossible(f))
+  return Self::castFailed();
+return doCast(f);
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-16 Thread Aman LaChapelle via Phabricator via cfe-commits
bzcheeseman added inline comments.



Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h:102
   template
   T castAs() const {
 assert(T::classof(*this));

Is it worth refactoring this and getAs to use `cast`  and `dyn_cast` as 
appropriate to avoid code duplication?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125709

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


[PATCH] D125709: [analyzer][Casting] Support isa, cast, dyn_cast of SVals

2022-05-16 Thread Balázs Benics via Phabricator via cfe-commits
steakhal created this revision.
steakhal added reviewers: NoQ, martong, Szelethus, balazske, ASDenysPetrov, 
bzcheeseman.
Herald added subscribers: manas, dkrupp, donat.nagy, mikhail.ramalho, 
a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun.
Herald added a project: All.
steakhal requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change specializes the LLVM RTTI mechanism for SVals.
After this change, we can use the well-known `isa`, `cast`, `dyn_cast`.

Examples:

  // SVal V = ...;
  // Loc MyLoc = ...;
  
  bool IsInteresting = isa(MyLoc);
  auto MRV = cast(MyLoc);
  Optional MaybeMRV = dyn_cast(V)

The current `SVal::getAs` and `castAs` member functions are redundant at
this point, but I believe that they are still handy.

The member function version is terse and reads left-to-right, which IMO
is a great plus. However, we should probably add a variadic `isa` member
function version to have the same casting API in both cases.

I'm not sure, shall I add tests?

Thanks for the extensive TMP help @bzcheeseman!


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125709

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h


Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -571,4 +571,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { return Optional{}; }
+  static Optional doCast(const From ) {
+return *static_cast(cast<::clang::ento::SVal>());
+  }
+  static Optional doCastIfPossible(const From ) {
+if (!Self::isPossible(f))
+  return Self::castFailed();
+return doCast(f);
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H


Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -571,4 +571,28 @@
 } // namespace ento
 } // namespace clang
 
+namespace llvm {
+template 
+struct CastInfo<
+To, From,
+std::enable_if_t::value>>
+: public CastIsPossible {
+  using Self = CastInfo<
+  To, From,
+  std::enable_if_t::value>>;
+  static bool isPossible(const From ) {
+return To::classof(*static_cast());
+  }
+  static Optional castFailed() { return Optional{}; }
+  static Optional doCast(const From ) {
+return *static_cast(cast<::clang::ento::SVal>());
+  }
+  static Optional doCastIfPossible(const From ) {
+if (!Self::isPossible(f))
+  return Self::castFailed();
+return doCast(f);
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits