[cfe-dev] GCC's "Temporaries May Vanish Before You Expect"

Sean Silva silvas at purdue.edu
Wed Sep 12 17:08:24 PDT 2012


Does that mean that:

doSomething(StrRef.str().c_str());

is unsafe?

because I've seen a couple of those around.

>   I->getAs<CFGStmt>()
>
> and
>
>   dyn_cast<CFGStmt>(&*I)
>
> , the latter of which is slightly more ugly.

Would it be possible to make dyn_cast a bit smarter so that it will
look into an iterator's member typedefs and automatically do the
trivial &* stuff itself?

--Sean Silva

On Wed, Sep 12, 2012 at 7:10 PM, Jordan Rose <jordan_rose at apple.com> wrote:
> Throughout Clang we have a dangerous little helper method that looks like this:
>
>   template<class T> const T *getAs() const {
>     if (isa<T>(this))
>       return static_cast<const T*>(this);
>     return 0;
>   }
>
> or sometimes, more simply
>
>   template<class T> const T *getAs() const {
>     return dyn_cast<T>(this);
>   }
>
> The problem? This method is very dangerous to use with value objects, since you could accidentally do this:
>
> CFGStmt *S = getTemporaryObject().getAs<CFGStmt>();
>
> And indeed we've found two such cases in the last week where we've actually done this in the analyzer (the value object being CFGElement).
>
> I'm half-inclined to remove 'getAs' from CFGElement, but it is useful when you are, say, iterating over a set of known-valid objects. It's the difference between
>
>   I->getAs<CFGStmt>()
>
> and
>
>   dyn_cast<CFGStmt>(&*I)
>
> , the latter of which is slightly more ugly.
>
> The thing that keeps me from removing it is that it IS more convenient and it CAN be made safe. The first way is to use C++11 to forbid the use of this function on rvalues; that looks like this:
>
>   template<class T> const T *getAs() const && = delete;
>   template<class T> const T *getAs() const & {
>     return dyn_cast<T>(this);
>   }
>
> This could be hidden behind a compatibility macro:
>
>   template<class T> const T *getAs() const LLVM_RVALUE_DELETE;
>   template<class T> const T *getAs() const LLVM_LVALUE {
>     return dyn_cast<T>(this);
>   }
>
> The second way is if -fcatch-undefined-behavior could be augmented to handle this case. I have no idea how to do this, though -- perhaps it requires something ASan-ish to poison the temporary memory once its lifetime ends.
>
> Any chance of either of these happening on trunk?
> Thanks,
> Jordan
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev



More information about the cfe-dev mailing list