From 344ef440eec3e49e9407ff08f1d4517f760fbb78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr>
Date: Tue, 20 Apr 2021 19:37:59 +0200
Subject: [PATCH] [kernel] Fixes a crash on __alignof__(void).

Catches the exception [SizeOfError] when using [Cil.bytesAlignOf].
---
 src/kernel_services/abstract_interp/base.ml | 16 +++++++++-------
 src/kernel_services/ast_queries/cil.ml      | 11 +++++++++--
 src/kernel_services/ast_queries/cil.mli     |  3 ++-
 src/plugins/e-acsl/src/analyses/interval.ml |  4 +++-
 4 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/src/kernel_services/abstract_interp/base.ml b/src/kernel_services/abstract_interp/base.ml
index 0bfde596c3a..9f5bc00b9ef 100644
--- a/src/kernel_services/abstract_interp/base.ml
+++ b/src/kernel_services/abstract_interp/base.ml
@@ -349,13 +349,15 @@ let is_aligned_by b alignment =
   if Int.is_zero alignment
   then false
   else
-    match b with
-    | Var (v,_) | Allocated(v,_,_) ->
-      Int.is_zero (Int.e_rem (Int.of_int (Cil.bytesAlignOf v.vtype)) alignment)
-    | CLogic_Var (_, ty, _) ->
-      Int.is_zero (Int.e_rem (Int.of_int (Cil.bytesAlignOf ty)) alignment)
-    | Null -> true
-    | String _ -> Int.is_one alignment
+    try
+      match b with
+      | Var (v,_) | Allocated(v,_,_) ->
+        Int.is_zero (Int.e_rem (Int.of_int (Cil.bytesAlignOf v.vtype)) alignment)
+      | CLogic_Var (_, ty, _) ->
+        Int.is_zero (Int.e_rem (Int.of_int (Cil.bytesAlignOf ty)) alignment)
+      | Null -> true
+      | String _ -> Int.is_one alignment
+    with Cil.SizeOfError _ -> false
 
 let is_any_formal_or_local v =
   match v with
diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml
index 81f75901401..203845899ac 100644
--- a/src/kernel_services/ast_queries/cil.ml
+++ b/src/kernel_services/ast_queries/cil.ml
@@ -4545,7 +4545,10 @@ and constFold (machdep: bool) (e: exp) : exp =
   | SizeOfStr s when machdep ->
     kinteger ~loc theMachine.kindOfSizeOf (1 + String.length s)
   | AlignOf t when machdep ->
-    kinteger ~loc theMachine.kindOfSizeOf (bytesAlignOf t)
+    begin
+      try kinteger ~loc theMachine.kindOfSizeOf (bytesAlignOf t)
+      with SizeOfError _ -> e
+    end
   | AlignOfE e when machdep -> begin
       (* The alignment of an expression is not always the alignment of its
        * type. I know that for strings this is not true *)
@@ -5223,7 +5226,11 @@ let rec constFoldTermNodeAtTop = function
     (try integer_lconstant (bytesSizeOf typ)
      with SizeOfError _ -> t)
   | TSizeOfStr str -> integer_lconstant (String.length str + 1)
-  | TAlignOf typ -> integer_lconstant (bytesAlignOf typ)
+  | TAlignOf typ as t ->
+    begin
+      try integer_lconstant (bytesAlignOf typ)
+      with SizeOfError _ -> t
+    end
   | TSizeOfE { term_type= Ctype typ } -> constFoldTermNodeAtTop (TSizeOf typ)
   | TAlignOfE { term_type= Ctype typ }
     -> 	constFoldTermNodeAtTop (TAlignOf typ)
diff --git a/src/kernel_services/ast_queries/cil.mli b/src/kernel_services/ast_queries/cil.mli
index 02f54e2f020..2613a70e4cf 100644
--- a/src/kernel_services/ast_queries/cil.mli
+++ b/src/kernel_services/ast_queries/cil.mli
@@ -2183,7 +2183,8 @@ val sizeOf: loc:location -> typ -> exp
 
 (** The minimum alignment (in bytes) for a type. This function is
  * architecture dependent, so you should only call this after you call
- * {!Cil.initCIL}. *)
+ * {!Cil.initCIL}.
+ * Raises {!SizeOfError} when it cannot compute the alignment. *)
 val bytesAlignOf: typ -> int
 
 (** [intOfAttrparam a] tries to const-fold [a] into a numeric value.
diff --git a/src/plugins/e-acsl/src/analyses/interval.ml b/src/plugins/e-acsl/src/analyses/interval.ml
index ab451611348..4668403ccdd 100644
--- a/src/plugins/e-acsl/src/analyses/interval.ml
+++ b/src/plugins/e-acsl/src/analyses/interval.ml
@@ -406,7 +406,9 @@ let infer_sizeof ty =
   try singleton_of_int (Cil.bytesSizeOf ty)
   with Cil.SizeOfError _ -> interv_of_typ Cil.theMachine.Cil.typeOfSizeOf
 
-let infer_alignof ty = singleton_of_int (Cil.bytesAlignOf ty)
+let infer_alignof ty =
+  try singleton_of_int (Cil.bytesAlignOf ty)
+  with Cil.SizeOfError _ -> interv_of_typ Cil.theMachine.Cil.typeOfSizeOf
 
 let rec infer t =
   let get_cty t = match t.term_type with Ctype ty -> ty | _ -> assert false in
-- 
GitLab