From 00792152880e063420d61b34893279ece57c5aa0 Mon Sep 17 00:00:00 2001 From: iphydf Date: Wed, 6 Mar 2024 16:26:51 +0000 Subject: [PATCH] feat: Add preliminary support for `owner` pointer qualifier. It doesn't do anything, but passes through and accepts them. --- src/Tokstyle/Common.hs | 1 + src/Tokstyle/Linter/Callgraph.hs | 3 +++ src/Tokstyle/Linter/CallocType.hs | 1 + src/Tokstyle/Linter/MallocType.hs | 15 ++++++++++----- src/Tokstyle/Linter/TypeCheck.hs | 1 + src/Tokstyle/SemFmt/EnumFromInt.hs | 2 +- stack.yaml | 2 +- test/Tokstyle/SemFmt/EnumFromIntSpec.hs | 22 +++++++++++----------- tokstyle.cabal | 2 +- 9 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/Tokstyle/Common.hs b/src/Tokstyle/Common.hs index 1a484ac..374868a 100644 --- a/src/Tokstyle/Common.hs +++ b/src/Tokstyle/Common.hs @@ -19,6 +19,7 @@ isPointer x = case unFix x of VarDecl ty _ [] -> isPointer ty VarDecl{} -> True TyConst ty -> isPointer ty + TyOwner ty -> isPointer ty TyPointer{} -> True TyStd{} -> False TyStruct{} -> False diff --git a/src/Tokstyle/Linter/Callgraph.hs b/src/Tokstyle/Linter/Callgraph.hs index e2b4bfd..aa7e966 100644 --- a/src/Tokstyle/Linter/Callgraph.hs +++ b/src/Tokstyle/Linter/Callgraph.hs @@ -339,6 +339,9 @@ analyse = reverse . flip State.execState [] . linter . (builtins <>) . callgraph , "WORDS_BIGENDIAN" + -- cake + , "static_set" + , "crypto_aead_xchacha20poly1305_ietf_decrypt" , "crypto_aead_xchacha20poly1305_ietf_encrypt" , "crypto_auth_BYTES" diff --git a/src/Tokstyle/Linter/CallocType.hs b/src/Tokstyle/Linter/CallocType.hs index 2d1a18f..027583c 100644 --- a/src/Tokstyle/Linter/CallocType.hs +++ b/src/Tokstyle/Linter/CallocType.hs @@ -26,6 +26,7 @@ checkTypes funName file castTy sizeofTy = case unFix castTy of "`" <> funName <> "` should not be used for `" <> showNode castTy <> "`; use `mem_balloc` instead" TyPointer ty1 | ty1 `semEq` sizeofTy -> return () + TyOwner (Fix (TyPointer ty1)) | ty1 `semEq` sizeofTy -> return () _ -> warn file castTy $ "`" <> funName <> "` result is cast to `" <> showNode castTy <> "` but allocated type is `" <> showNode sizeofTy <> "`" diff --git a/src/Tokstyle/Linter/MallocType.hs b/src/Tokstyle/Linter/MallocType.hs index 7de3150..5f0d645 100644 --- a/src/Tokstyle/Linter/MallocType.hs +++ b/src/Tokstyle/Linter/MallocType.hs @@ -30,6 +30,10 @@ isByteSize ty = case unFix ty of TyStd (L _ _ "uint8_t") -> True _ -> False +removeOwner :: Node (Lexeme Text) -> Node (Lexeme Text) +removeOwner (Fix (TyOwner ty)) = ty +removeOwner ty = ty + checkType :: FilePath -> Text -> Node (Lexeme Text) -> State [Text] () checkType file malloc castTy = case unFix castTy of TyPointer (Fix (TyStd (L _ _ tyName))) | tyName `elem` supportedTypes -> return () @@ -74,14 +78,15 @@ linter = astActions { doNode = \file node act -> case unFix node of -- Windows API weirdness: ignore completely. - CastExpr (Fix (TyPointer (Fix (TyStd (L _ _ "IP_ADAPTER_INFO"))))) _ -> return () + CastExpr (Fix (TyPointer (Fix (TyStd (L _ _ "IP_ADAPTER_INFO"))))) _ -> return () + CastExpr (Fix (TyOwner (Fix (TyPointer (Fix (TyStd (L _ _ "IP_ADAPTER_INFO"))))))) _ -> return () CastExpr castTy (Fix (FunctionCall (Fix (VarExpr (L _ _ "malloc"))) [size])) -> do - checkType file "malloc" castTy - checkSize file "malloc" castTy size + checkType file "malloc" (removeOwner castTy) + checkSize file "malloc" (removeOwner castTy) size CastExpr castTy (Fix (FunctionCall (Fix (VarExpr (L _ _ "mem_balloc"))) [_, size])) -> do - checkType file "mem_balloc" castTy - checkSize file "mem_balloc" castTy size + checkType file "mem_balloc" (removeOwner castTy) + checkSize file "mem_balloc" (removeOwner castTy) size FunctionCall (Fix (VarExpr (L _ _ name))) _ | name `elem` mallocs -> warn file node $ "the result of `" <> name <> "` must be cast; plain `void *` is not supported" diff --git a/src/Tokstyle/Linter/TypeCheck.hs b/src/Tokstyle/Linter/TypeCheck.hs index 9a7c129..8058dbe 100644 --- a/src/Tokstyle/Linter/TypeCheck.hs +++ b/src/Tokstyle/Linter/TypeCheck.hs @@ -344,6 +344,7 @@ inferTypes = \case TyBitwise ty -> return ty TyForce ty -> return ty TyConst ty -> return ty + TyOwner ty -> return ty Ellipsis -> return T_Void VLA ty (L _ _ name) size -> do diff --git a/src/Tokstyle/SemFmt/EnumFromInt.hs b/src/Tokstyle/SemFmt/EnumFromInt.hs index 679a786..f32cf61 100644 --- a/src/Tokstyle/SemFmt/EnumFromInt.hs +++ b/src/Tokstyle/SemFmt/EnumFromInt.hs @@ -29,7 +29,7 @@ mkCase node = error $ show node mkAssignOut :: Lexeme Text -> (LexemeClass, Text) -> Node (Lexeme Text) mkAssignOut name (retCls, retStr) = - let outDeref = Fix (UnaryExpr UopDeref (Fix (VarExpr (mkLAt name IdVar "out")))) in + let outDeref = Fix (UnaryExpr UopDeref (Fix (VarExpr (mkLAt name IdVar "out_enum")))) in Fix $ CompoundStmt [ Fix (ExprStmt (Fix (AssignExpr outDeref AopEq (Fix (LiteralExpr ConstId name))))) , Fix (Return (Just (Fix (LiteralExpr Bool (mkLAt name retCls retStr))))) diff --git a/stack.yaml b/stack.yaml index e107986..b8007ba 100644 --- a/stack.yaml +++ b/stack.yaml @@ -2,4 +2,4 @@ packages: [.] resolver: lts-21.9 extra-deps: - - cimple-0.0.20 + - cimple-0.0.21 diff --git a/test/Tokstyle/SemFmt/EnumFromIntSpec.hs b/test/Tokstyle/SemFmt/EnumFromIntSpec.hs index 14adb6c..fede777 100644 --- a/test/Tokstyle/SemFmt/EnumFromIntSpec.hs +++ b/test/Tokstyle/SemFmt/EnumFromIntSpec.hs @@ -17,18 +17,18 @@ spec = do , " FOO_ONE," , " FOO_TWO," , "} Foo;" - , "bool foo_from_int(int b, Foo *out) {" + , "bool foo_from_int(int b, Foo *out_enum) {" , " switch (b) {" , " case FOO_ONE: {" - , " *out = FOO_ONE;" + , " *out_enum = FOO_ONE;" , " return true;" , " }" , " case FOO_TWO: {" - , " *out = FOO_ONE;" -- mistake here + , " *out_enum = FOO_ONE;" -- mistake here , " return true;" , " }" , " default: {" - , " *out = FOO_ONE;" + , " *out_enum = FOO_ONE;" , " return false;" , " }" , " }" @@ -38,15 +38,15 @@ spec = do [ "{" , " switch (b) {" , " case FOO_ONE: {" - , " *out = FOO_ONE;" + , " *out_enum = FOO_ONE;" , " return true;" , " }" , " case FOO_TWO: {" - , " *out = FOO_TWO;" + , " *out_enum = FOO_TWO;" , " return true;" , " }" , " default: {" - , " *out = FOO_ONE;" + , " *out_enum = FOO_ONE;" , " return false;" , " }" , " }" @@ -64,18 +64,18 @@ spec = do , " FOO_ONE," , " FOO_TWO," , "} Foo;" - , "bool foo_from_int(int b, Foo *out) {" + , "bool foo_from_int(int b, Foo *out_enum) {" , " switch (b) {" , " case FOO_ONE: {" - , " *out = FOO_ONE;" + , " *out_enum = FOO_ONE;" , " return true;" , " }" , " case FOO_TWO: {" - , " *out = FOO_TWO;" + , " *out_enum = FOO_TWO;" , " return true;" , " }" , " default: {" - , " *out = FOO_ONE;" + , " *out_enum = FOO_ONE;" , " return false;" , " }" , " }" diff --git a/tokstyle.cabal b/tokstyle.cabal index bb55986..6021431 100644 --- a/tokstyle.cabal +++ b/tokstyle.cabal @@ -82,7 +82,7 @@ library , array <0.6 , base >=4 && <5 , bytestring <0.13 - , cimple >=0.0.20 + , cimple >=0.0.21 , casing <0.2 , containers <0.8 , data-fix <0.4