r273911 - [ExprConstant] Fix PR28314 - crash while evluating objectsize.
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 28 08:42:05 PDT 2016
+Tom who does the "dot" releases.
I don't know if he's planning for a 3.8.2, but just in case, I suppose
it's on the radar now :-)
Thanks,
Hans
On Mon, Jun 27, 2016 at 11:21 PM, George Burgess IV
<george.burgess.iv at gmail.com> wrote:
> +Richard, Hans
>
> This patch fixes a crash that's also present in Clang 3.8. So, I think it
> should find its way into 3.8.2, if possible.
>
> Thank you! :)
>
> ---------- Forwarded message ----------
> From: George Burgess IV via cfe-commits <cfe-commits at lists.llvm.org>
> Date: Mon, Jun 27, 2016 at 12:40 PM
> Subject: r273911 - [ExprConstant] Fix PR28314 - crash while evluating
> objectsize.
> To: cfe-commits at lists.llvm.org
>
>
> Author: gbiv
> Date: Mon Jun 27 14:40:41 2016
> New Revision: 273911
>
> URL: http://llvm.org/viewvc/llvm-project?rev=273911&view=rev
> Log:
> [ExprConstant] Fix PR28314 - crash while evluating objectsize.
>
> This fixes a crash in code like:
> ```
> struct A {
> struct B b;
> char c[1];
> }
>
> int foo(struct A* a) { return __builtin_object_size(a->c, 0); }
> ```
>
> We wouldn't check whether the structs we were examining were invalid,
> and getting the layout of an invalid struct is (unsurprisingly) A Bad
> Thing. With this patch, we'll always return conservatively if we see an
> invalid struct, since I'm assuming the presence of an invalid struct
> means that our compilation failed (so having a conservative result isn't
> such a big deal).
>
> Modified:
> cfe/trunk/lib/AST/ExprConstant.cpp
> cfe/trunk/test/Sema/builtin-object-size.c
>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=273911&r1=273910&r2=273911&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Jun 27 14:40:41 2016
> @@ -6540,25 +6540,32 @@ static const Expr *ignorePointerCastsAnd
> ///
> /// Please note: this function is specialized for how __builtin_object_size
> /// views "objects".
> +///
> +/// If this encounters an invalid RecordDecl, it will always return true.
> static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue
> &LVal) {
> assert(!LVal.Designator.Invalid);
>
> - auto IsLastFieldDecl = [&Ctx](const FieldDecl *FD) {
> - if (FD->getParent()->isUnion())
> + auto IsLastOrInvalidFieldDecl = [&Ctx](const FieldDecl *FD, bool
> &Invalid) {
> + const RecordDecl *Parent = FD->getParent();
> + Invalid = Parent->isInvalidDecl();
> + if (Invalid || Parent->isUnion())
> return true;
> - const ASTRecordLayout &Layout =
> Ctx.getASTRecordLayout(FD->getParent());
> + const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Parent);
> return FD->getFieldIndex() + 1 == Layout.getFieldCount();
> };
>
> auto &Base = LVal.getLValueBase();
> if (auto *ME = dyn_cast_or_null<MemberExpr>(Base.dyn_cast<const Expr
> *>())) {
> if (auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
> - if (!IsLastFieldDecl(FD))
> - return false;
> + bool Invalid;
> + if (!IsLastOrInvalidFieldDecl(FD, Invalid))
> + return Invalid;
> } else if (auto *IFD =
> dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
> - for (auto *FD : IFD->chain())
> - if (!IsLastFieldDecl(cast<FieldDecl>(FD)))
> - return false;
> + for (auto *FD : IFD->chain()) {
> + bool Invalid;
> + if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid))
> + return Invalid;
> + }
> }
> }
>
> @@ -6581,8 +6588,9 @@ static bool isDesignatorAtObjectEnd(cons
> return false;
> BaseType = CT->getElementType();
> } else if (auto *FD = getAsField(LVal.Designator.Entries[I])) {
> - if (!IsLastFieldDecl(FD))
> - return false;
> + bool Invalid;
> + if (!IsLastOrInvalidFieldDecl(FD, Invalid))
> + return Invalid;
> BaseType = FD->getType();
> } else {
> assert(getAsBaseClass(LVal.Designator.Entries[I]) != nullptr &&
>
> Modified: cfe/trunk/test/Sema/builtin-object-size.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-object-size.c?rev=273911&r1=273910&r2=273911&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/builtin-object-size.c (original)
> +++ cfe/trunk/test/Sema/builtin-object-size.c Mon Jun 27 14:40:41 2016
> @@ -52,3 +52,27 @@ void f6(void)
> __builtin___memccpy_chk (buf, b, '\0', sizeof(b), __builtin_object_size
> (buf, 0));
> __builtin___memccpy_chk (b, buf, '\0', sizeof(buf), __builtin_object_size
> (b, 0)); // expected-warning {{'__builtin___memccpy_chk' will always
> overflow destination buffer}}
> }
> +
> +int pr28314(void) {
> + struct {
> + struct InvalidField a; // expected-error{{has incomplete type}}
> expected-note 3{{forward declaration of 'struct InvalidField'}}
> + char b[0];
> + } *p;
> +
> + struct {
> + struct InvalidField a; // expected-error{{has incomplete type}}
> + char b[1];
> + } *p2;
> +
> + struct {
> + struct InvalidField a; // expected-error{{has incomplete type}}
> + char b[2];
> + } *p3;
> +
> + int a = 0;
> + a += __builtin_object_size(&p->a, 0);
> + a += __builtin_object_size(p->b, 0);
> + a += __builtin_object_size(p2->b, 0);
> + a += __builtin_object_size(p3->b, 0);
> + return a;
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list